/**************************************************************************
 * @doc CPAC
 * @module CPAC.C |
 * Source code for the CPAC handling functions.
 *
 * Product         :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team (I_SP2000).
 * <nl>Notes       :
 *
 * @head3 CPAC Functions |
 * @index | CPAC
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 $Log: /SoftPay/SPK2SIM/Source/CPACSrc/cpacsrc.c $
 ********************************************************************************/
#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#include <project.h>
#define CPAC_C
#ifdef ICICI
#define HDFC_INDIA 1
#endif  /* ICICI   */
#include<amexhost.h>
#include <aclconio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>    
#include <acldev.h>
#include <aclstr.h>
#include <aclutil.h>
#include <prot8583.h>
#include <define.h>
#include <transact.h>
#include <dbmgr.h>
#include <svc.h>
#include <power.h> 

#include <entry.h>   
#include <pinpad.h>  
#include <protocol.h>
#include <packet.h>
#include <tran.h>
#include <comm.h>
#include <modem.h>
#include <ppt.h>
#include <piputl.h>
#include <pipmsg.h>
#include <isoutl.h>
#include <isoload.h>
#include <ifldtbl.h>
#include <msg.h>
#include <msgfuncs.h>
#include <bdt.h>
#include <hdt.h>
#include <trt.h>
#include <mht.h>
#include <iit.h>
#include <accum.h>
#include <form.h>
#include <date.h>
#include <mem.h>
#include <spdebug.h>
#include <funcids.h>
#include <pbatch.h>
#include <errno.h>
#include <ascii.h>
#include <amexhost.h>
#include <pct.h>
#include <formater.h>
#include <table.h>
#include <string.h>
#include <confio.h>
#include <aclfile.h>
#include <format.h>
#include <spamsg.h>
#include <oper.h>
#include <batmsg.h>
#include <ui.h>
#include <tct.h>
#include <multilng.h>
#include <logo.h>
#include <settlbat.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <menufunc.h>
#include <mit.h>
#include <applidl.h>
#include <tblutil.h>                                                        //CPAC2.1B
#include <menus.h>
#include <Validt.h>
#include <sizes.h>
#include <card.h> 

#include <print.h>
#include <Modemmsg.h>   
#include <xmodem.h>		
#include <rs232.h>      
#include <protfunc.h>  
#include <aclascii.h>   
#include <stats.h>      

#include "..\imamsrc\imamsrc.h"
#include "..\imamsrc\imammenu.h"

#include "cpacsize.h"
#include "cpacids.h"
#include "cpacsrc.h"
#include "cpacbat.h"
#include "cpacmsg.h"
#include "cpacoper.h"
#include "cpatran.h"
#include "cpacprnt.h"
#include "cpacstl.h"
#include "custoper.h"
#include "cpacextn.h"
#include "sqautils.h"
#include "rcptsegs.h"

#ifdef HDFC_INDIA
#include "..\ICICSrc\ICICSrc.h"
#include "..\ICICSRC\icicids.h"
#endif /* HDFC_INDIA */

#ifdef VXEMVAPP
#include <EMVCWrappers.h>
#include <vxemvap.h>
#include "..\emvsrc\emvsrcdef.h"
#include "..\emvsrc\emvcall.h"
#endif
#ifdef CPACCLRK_C
#include "cpacclrk.h"
#endif /* CPACCLRK_C */

#define TWELVE_ZEROS "000000000000"
#define MANUAL_CITI_IND_POS_ENTRY_CODE  "010"
#define SWIPE_CITI_IND_POS_ENTRY_CODE   "020"
#define vdGetCPACTermID(pchTermID) \
    strlcpy(pchTermID, srCPAC.szCPACTID, CPAC_TERM_ID_SIZE)
#define vdGetCPACMerchID(pchMerchID) \
    strlcpy(pchMerchID, srCPAC.szCPACMID, CPAC_MERCH_ID_SIZE)
#define vdGetCPACNII(pchNII) \
    strlcpy(pchNII, srCPAC.szCPACNII, CPAC_NII_SIZE)
#define vdGetCPACDescCode(pchDescCode) \
    strlcpy(pchDescCode, srCPAC.szCPACDescCode, CPAC_PVT_61_SIZE)
#define SIZE_CPAC_REC        REC_SIZEOF(CPAC_REC)

#define CPAC_AUTO_SETTLE_LOOK_UP_TIME   480 //480= (1/250)*1000*60*2 = 480check for AS every 2 mints.
#define AXAP_COMM_ERROR   -700
//ADD_VALIDATION_STRUCT srAddValStruct;                 //sowmya_to_check
//ADD_VALIDATION_STRUCT srRevValStruct;                 //sowmya_to_check
int inCPACPrintLineFeed(TRANSACTION_OBJECT* pobTran/*, PRINTER_OBJECT *obPrinter*/);
int inSetToMainMenu(TRANSACTION_OBJECT* pobTran);

int inCPACRenameReversalFile(TRANSACTION_OBJECT* pobTran);
int inCPACLoadVoidIssueNumber(TRANSACTION_OBJECT* pobTran);
int inClearCHolder(TRANSACTION_OBJECT* pobTran);
int inClearErrorMsg(TRANSACTION_OBJECT* pobTran);
int inCPACCloseFormaterHandle(TRANSACTION_OBJECT* pobTran);
extern int inGetInvoiceNumber(TRANSACTION_OBJECT* pobTran);
extern void vdOverLoadLoadDataFuncs(ISOLOAD srNewLoadDataFuncs[]);
extern HOST_8583_DATA* psrCreateHostData(void);
//int inCPACGetMerchEnable(void);
extern int inCPACBaseRespValidation(VALIDATION_STRUCT* psrRespValStruct,int  inInternalVal);
extern int inCheckBannedCardType(TRANSACTION_OBJECT* pobTran); //CPAC_AMEX
extern int inLoadCDTRec(int inCDTRecNumber);
extern int inGetMerchPassword(TRANSACTION_OBJECT* pobTran);
extern int inResetDemoBatch(TRANSACTION_OBJECT* pobTran);
extern  int get_env_x(char *param, int n, char *buff);
extern void vdDisplayNoDataMsg(void);
extern char* szGetTracks(void); // 1.4
#ifdef AMEX_PROC_CODE_CHNG
extern int inAdvCnt;
#endif  /* AMEX_PROC_CODE_CHNG */

#ifdef UPDATE_ADV_STAN
// int inCPACModifyAdvice (TRANSACTION_OBJECT *pobTran);
int inCPACModifyAdvice(HOST_8583_DATA* host_struct);
#endif /*  UPDATE_ADV_STAN  */

#ifdef UPDATE_REV_STAN
//int inCPACModifyReversal (TRANSACTION_OBJECT *pobTran, HOST_8583_DATA *host_struct);
int inCPACModifyReversal(TRANSACTION_OBJECT* pobTran);
#endif  /*  UPDATE_REV_STAN */

#ifdef AMEX_PROC_CODE_CHNG

extern int inAXAPModifyAdvProcCode0(HOST_8583_DATA* host_struct);
extern int inAXAPModifyAdvProcCode1(HOST_8583_DATA* host_struct);

#endif /*  AMEX_PROC_CODE_CHNG */

#ifdef VXEMVAPP
extern int inGlobalNumberScripts;
#endif

extern int search_roc(int,unsigned char*,int);
extern int delete_roc(int f_handle,int record_number);
extern int inChkFileExist(const char* szFileName);
extern VS_BOOL fFPSQualified(TRANSACTION_OBJECT* pobTran);
extern int disasm_8583_rec(COMM_8583_DATA* control,BYTE src);
int inGlobalMerchantHandle;
int inGlobalAutoHandle ;
int inGCPACHostSelectedIndex = 0;
#ifdef TCPIP_DEFINED
int hLan;

int hSocket;
int inSendConnectOneCmd(int hConnectOne,int iLen,char* cmd_buff);
int inGetConnectOneResponse(int hConnect,int i_max_wait,char* pbuffer);

#endif  /* TCPIP_DEFINED */


extern PCT_REC srPCTRec;
extern int inGlobalHostHandle;
extern unsigned long lnMiddleCondition;
extern int inImamLineNumber;
extern int inImamLogonNow;
extern SMenu *ImamActiveMenu;
int inImamRestartFlag = 0;

ISOLOAD srCPACLoadDataFuncs[] = {
    2,
    vdLoadField02,
    3,
    vdDummy,
    4,
    vdLoadCPACField04,
    11,
    vdLoadField11,
    12,
    vdLoadField12,
    13,
    vdLoadField13,
    14,
    vdLoadCPACField14,
    22,
    vdLoadCPACField22,
    24,
    vdLoadCPACField24,
    25,
    vdLoadField25,
    35,
    vdLoadField35,
    37,
    vdLoadCPACField37,
    38,
    vdLoadField38,
    39,
    vdLoadCPACField39,
    41,
    vdLoadCPACField41,
    42,
    vdLoadCPACField42,
    44,
    vdDummy,
    45,
    vdLoadField45,
    #ifdef CITI_IND
    48,
    vdLoadCPACField48,
    #endif /* CITI_IND */
	52, 
	vdLoadCPACField52,
    54,
    vdLoadCPACField54,
    60,
    vdLoadCPACField60,
    61,
    vdLoadCPACField61,
    62,
    vdLoadCPACField62,
    63,
    vdLoadCPACField63,
	64, vdLoadCPACField64
};



/*********************************************************************************************
* @func int | inCPACCreateVariantStruct60 |
* This routine takes care of allocating the space and loading the Variant field
* table 60 for CPAC.
*
* @devnote This is an obHost function
*
* @rdesc Returns the success.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inCPACCreateVariantStruct60(void) {
    short i;

    variant_struct* tmp;

    if ((tmp = (variant_struct *) pchAlloc(CPAC_TABLE60_SIZE * sizeof(variant_struct))) == NULL_CH) {
        ACTIVITY_LOG("Variant 60 memory alloc!");
        return (VS_ERR);
    }

    psrVariant60 = tmp;
/*
	 variant_struct srBaseVariant60 [] =
        {
		{ 92,    500,  6, AV3_STR, (void *)srISO.pszField60), sizeof(srISO.pszField60)},
            	{ 96,    500,  6, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 97,    500,  6, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 00,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 02,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 20,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
              { 22,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 09,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 29,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
		{ 00,    420, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
		{ 02,    420, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
		{ 22,    420, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
		{ 02,    220, 12, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
            }; */
    for (i = 0; i < CPAC_TABLE60_SIZE; i++) {
        tmp->convert_idx = AV3_STR;
        if (i < 15) {
            tmp->reference = (void *) srISO.pszField60;
            tmp->var_sz = sizeof(srISO.pszField60);
        }
        if (i < 3) {
            tmp->variant2 = 500;
            tmp->packet_sz = 6;
        } else
            tmp->packet_sz = 22;

        switch (i) {
        case 0:
            tmp->variant1 = 92;
            break;
        case 1:
            tmp->variant1 = 96;
            break;
        case 2:
            tmp->variant1 = 97;
            break;
        case 3:
            tmp->variant1 = 00;
            tmp->variant2 = 320;
            break;
        case 4:
            tmp->variant1 = 2;
            tmp->variant2 = 320;
            break;
        case 5:
            tmp->variant1 = 20;
            tmp->variant2 = 320;
            break;
        case 6:
            tmp->variant1 = 22;
            tmp->variant2 = 320;
            break;
        case 7:
            tmp->variant1 = 9;
            tmp->variant2 = 320;
            break;
        case 8:
            tmp->variant1 = 29;
            tmp->variant2 = 320;
            break;
        case 9:
            tmp->variant1 = 0;
            tmp->variant2 = 420;
            break;
        case 10:
            tmp->variant1 = 2;
            tmp->variant2 = 420;
            break;
        case 11:
            tmp->variant1 = 22;
            tmp->variant2 = 420;
            break;
        case 12:
            tmp->variant1 = 2;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;
            break;
        case 13:
            tmp->variant1 = 22;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;
            break;
        case 14:
            tmp->variant1 = 0 + STOP;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;
            break;
        }
        tmp++;
    }

    srBaseIsoFDT[FIELD60_POSITION].reference = (void *) psrVariant60;

    /*
        variant_struct srBaseVariant60 [] =
        {
        0  { 92,    500,  6, AV3_STR, VARIABLE(srISO.pszField60) },
            1  { 96,    500,  6, AV3_STR, VARIABLE(srISO.pszField60) },
            2  { 97,    500,  6, AV3_STR, VARIABLE(srISO.pszField60) },
            3  { 00,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            4  { 02,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            5  { 20,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            6  { 22,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            7  { 09,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            8  { 29,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            };
        */
    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inCPACCreateVariantStruct63 |
* This routine takes care of allocating the space and loading the Variant field
* table 63 for CPAC.
*
* @devnote This is an obHost function
*
* @rdesc Returns the success.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inCPACCreateVariantStruct63(void) {
    short i;
    variant_struct* tmp;

    if ((tmp = (variant_struct *) pchAlloc(CPAC_TABLE63_SIZE * sizeof(variant_struct))) == NULL_CH) {
        ACTIVITY_LOG("Variant 60 memory alloc!");
        return (VS_ERR);
    }

    psrVariant63 = tmp;

    for (i = 0; i < CPAC_TABLE63_SIZE; i++) {
        tmp->convert_idx = AV3_STR;
        tmp->reference = (void *) srISO.pszField63;
        tmp->var_sz = sizeof(srISO.pszField63);
        if (i < 5) {
            tmp->variant2 = 500;
            tmp->packet_sz = 90;
        } else if ( i != CPAC_TABLE63_SIZE-1) { //: slight change
            tmp->variant2 = 510;
            tmp->packet_sz = 90; /* 40-> 90 CPAC_UNBKL */
        } else {
            tmp->variant2 = 510;
            tmp->packet_sz = 90; /* 40-> 90 CPAC_UNBKL */
        }

        switch (i) {
        case 0:
            tmp->variant1 = 92;
            break;
        case 1:
            tmp->variant1 = 93;
            break;
        case 2:
            tmp->variant1 = 94;
            break;
        case 3:
            tmp->variant1 = 96;
            break;
        case 4:
            tmp->variant1 = 97;
            break;
        case 5:
            tmp->variant1 = 96;
            break;
        case 6:
            tmp->variant1 = 93;
            break;
        case 7:
            tmp->variant1 = 94;
            break;
		case 8:	tmp->variant1 = 00;  // Sale Permata, and debit BNI
			tmp->variant2 = 210;
			tmp->packet_sz = 143; 
			break;
		case 9:	
			tmp->variant1 = 2;  // Void BNI
			tmp->variant2 = 210;
			tmp->packet_sz = 143;
			break;
		case 10:	
			tmp->variant1 = 38;  // PreAuth Permata
			tmp->variant2 = 110;
			tmp->packet_sz = 143;
			break;
		case 11:tmp->variant1 = 20;  // Refund Permata
			tmp->variant2 = 210;
			tmp->packet_sz = 90;
			break;
		case 12:tmp->variant1 = 00;  //SALE AIRLINE REQUEST
			tmp->variant2 = 200;
			tmp->packet_sz = 90;
		//break;
#ifdef IMAM_CR2
			tmp->convert_idx = AV3_AV3;
#endif
			break;
		case 13:tmp->variant1 = 00;  //EMA : PURCHASE
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 14:tmp->variant1 = 50;  //EMA : ISI ULANG/PAYMENT
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 15:tmp->variant1 = 80;  //EMA : REGISTRASI MB
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 16:tmp->variant1 = 31;  //EMA : INFO SALDO
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 17:tmp->variant1 = 38;  //EMA : MINI STATEMENT
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 18:tmp->variant1 = 39;  //EMA : INFO CCard
			tmp->variant2 = 310;
			tmp->packet_sz = 99;
			break;
		case 19:tmp->variant1 = 38;  //EMA : INFO BILL
			tmp->variant2 = 310;
			tmp->packet_sz = 99;
			break;
		case 20:tmp->variant1 = 40;  //EMA : TRF 2 CIF
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 21:tmp->variant1 = 49;  //EMA : TRF 2 OTHERS BANK
			tmp->variant2 = 210;
			tmp->packet_sz = 99;
			break;
		case 22:tmp->variant1 = 00;  //EMA : PURCHASE
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 23:tmp->variant1 = 50;  //EMA : ISI ULANG/PAYMENT
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 24:tmp->variant1 = 80;  //EMA : REGISTRASI MB
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 25:tmp->variant1 = 31;  //EMA : INFO SALDO
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 26:tmp->variant1 = 38;  //EMA : MINI STATEMENT
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 27:tmp->variant1 = 39;  //EMA : INFO CCard
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 28:tmp->variant1 = 38;  //EMA : INFO BILL
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 29:tmp->variant1 = 40;  //EMA : TRF 2 CIF
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 30:tmp->variant1 = 49;  //EMA : TRF 2 OTHERS BANK
			tmp->variant2 = 110;
			tmp->packet_sz = 99;
			break;
		case 31:tmp->variant1 = 92;  //RESP LOGON
			tmp->variant2 = 810;
			tmp->packet_sz = 99;
			break;
        case 32:
            tmp->variant1 = 92 + STOP;
            break;
        }
        tmp++;
    }
    srBaseIsoFDT[FIELD63_POSITION].packet_sz = 0;
    srBaseIsoFDT[FIELD63_POSITION].var_sz = 0;
    srBaseIsoFDT[FIELD63_POSITION].convert_idx = VARIANT;
    srBaseIsoFDT[FIELD63_POSITION].reference = (void *) psrVariant63;

    /*  psrVariant63[] =
    {
    { 92,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 93,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 94,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 96,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 97,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 96,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 93,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 94,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 92,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    };
    */
    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func void |  vdInitializeCPACValidationStruct |
* Initializes the validation structure.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @parm VALIDATION_STRUCT * | psrValidationParameters |
*       Validation structure.
*
* @end
**********************************************************************************************/

int inInitializeCPACValidationStruct(TRANSACTION_OBJECT* pobTran,VALIDATION_STRUCT* psrValidationParameters) {
    /** /pdebug(("--vdInitializeCPACValidationStruct--"));*/
    vdLoadField11(pobTran);                                              /* Load the STAN into the field struct variable */
    vdLoadCPACField42(pobTran);                                          /* Load the Merchant ID into the field struct variable*/
    psrValidationParameters->p_trace = &srISO.lnField11;
    /** /pdebug (("p_trace = %ld", *psrValidationParameters->p_trace));*/
    psrValidationParameters->b_trace = srISO.lnField11;
    /** /pdebug (("p_trace = %ld", psrValidationParameters->b_trace));*/
    psrValidationParameters->p_tid = (unsigned char *) srISO.pszField41;
    vdLoadCPACField41(pobTran);  /* Load the terminal ID into the field struct variable*/
    strlcpy((char *) psrValidationParameters->b_tid, (char *) srISO.pszField41, TERM_ID_SIZE);
    vdLoadCPACField04(pobTran);   /* Load the Amount Field */
    psrValidationParameters->p_amount = (unsigned char *) srISO.pszField04;
    strlcpy((char *) psrValidationParameters->b_amount, (char *) srISO.pszField04, ISO_AMT_SIZE);
    psrValidationParameters->curr_key = (unsigned char *) pszFieldROC;
    vdLoadCPACField62(pobTran);  /* get the correct ROC number based on transaction */
    strlcpy((char *) pszFieldROC, (char *) srISO.pszField62, inGetSTANSize());
    vdLoadCPACField37(pobTran);    /* Load Ret Ref Num     */
    strlcpy((char *) psrValidationParameters->b_rrn, (char *) srISO.pszField37, RET_REF_SIZE);
    return (VS_SUCCESS);
}


/*********************************************************************************************
* @func void | vdAddCPACFunctions |
*       Adds the CPAC packet initialization and communication functions
*       to the function table flexi record.
*
* @end
**********************************************************************************************/

void vdAddCPACFunctions(void) {
    inAddFunctionPointer(CPAC_INIT_PACKET, (PFI) vdInitializeCPAC);         /* Added (PFI) CPAC_UNBKL */
    inAddFunctionPointer(SET_CPAC_OFF_ONLINE, inSetCPACOffOnLine);
    inAddFunctionPointer(SEND_CPAC_PACKET, (PFI_TO) inSendReceiveCPAC);
    inAddFunctionPointer(VERIFY_CPAC_TRANS_TYPE, (PFI) shVerifyCPACTransType);
    inAddFunctionPointer(SETTLE_CPAC, (PFI_TO) inSettleCPAC);
    inAddFunctionPointer(CPAC_RECEIPT_FIELDS, inGetCPACReceiptFields);
    inAddFunctionPointer(CPAC_PRINT_RECEIPT_TOP, inCPACPrintReceiptTop);
    inAddFunctionPointer(CPAC_PRINT_RCPT_BOTTOM, inCPACPrintReceiptBottom);
    inAddFunctionPointer(CPAC_PRINT_REPORT_HEADER, inCPACPrintReportHeader);
    inAddFunctionPointer(CPAC_PRINT_REPORT_INIT, inCPACReportInit);
    inAddFunctionPointer(CPAC_PRINT_SUMMARY_REPORT, inCPACSummaryReportOperation);
#ifdef CLERK_DEFINED
    inAddFunctionPointer(CPAC_PRINT_CLERK_DETAIL_REPORT, inCPACClerkDetailReportOperation);
    inAddFunctionPointer(CPAC_PRINT_CLERK_TOTALS_REPORT, inCPACClerkTotalsReportOperation);
    inAddFunctionPointer(CPAC_PRINT_CLERK_TABLE_REPORT, inCPACClerkTableReportOperation);
#endif  /* CLERK_DEFINED */
    // #ifdef HKGM
    inAddFunctionPointer(CPAC_PRINT_STATS_REPORT, inCPACStatReportOperation);
    //#endif /* HKGM */

    inAddFunctionPointer(CPAC_REPRINT_SUMMARY_REPORT, inCPACRePrintSettlementReport);

#ifdef HKGM
    inAddFunctionPointer(HKGM_REPRINT_LAST_RECEIPT, inHKGMReprintLastReceiptOperation);
    inAddFunctionPointer(HKGM_REPRINT_ANY_RECEIPT, inHKGMReprintAnyReceiptOperation);
    inAddFunctionPointer(HKGM_GET_RECEIPT_COPY, inHKGMGetReceiptCopy);
#endif /* HKGM */

    inAddFunctionPointer(CPAC_UPDATE_BATCH, inFormCPACBatch);
    //  inAddFunctionPointer( INIT_VERIPRINT, inInitVeriPrint);
    //  inAddFunctionPointer( INIT_VP_HANDLE, inInitVPHandle);
    inAddFunctionPointer(CPAC_ADJUST, inCPACAdjust);
    inAddFunctionPointer(CPAC_ADJUST_AMOUNT, inGetCPACAdjustAmount);

#ifdef HKGM
    inAddFunctionPointer(CPAC_TIP_ADJUST_AMOUNT, inHKGMTipAdjust);
#else
    inAddFunctionPointer(CPAC_TIP_ADJUST_AMOUNT, inCPACTipAdjust);
#endif /* HKGM */

    inAddFunctionPointer(CPAC_BATCH_TOTALS_OPERATION, inCPACBatchTotalsOperation);
    inAddFunctionPointer(CPAC_VOID_YESNO_OPERATION, inCPACVoidYesNo);
    inAddFunctionPointer(CPAC_CLOSE_TAB_OPERATION, inGetCPACCloseTabAmount);
    inAddFunctionPointer(CPAC_CHK_BATCH_OPERATION, inCPACChkBatchEmpty);
    /*  inAddFunctionPointer( CITI_IND_PRINT_STATS_REPORT, inCPACStatReportOperation); */
    inAddFunctionPointer(ERR_CPAC_REPORT_OPERATION, inCPACPrintErrorReport);
    inAddFunctionPointer(CPAC_FIND_HANDLES_OPERATION, inCPACFindHandlesLeft);
    inAddMessageFileName(CPAC_NAME_ID, "cmsg");                         /* Adding custom Message filename */
    //  inAddFunctionPointer( SET_CPAC_STATUS_LINE, inSetCPACStatusLine);
    inAddFunctionPointer(CPAC_GET_INV_NUM, inCPACGetInvNum);
    inAddFunctionPointer(CPAC_GET_INVOICE_NUM, inCPACGetInvoiceNumber);
    inAddFunctionPointer(CPAC_CHECK_DO_AUTOSETTLE, inCPACCheckAndDoAutoSettle);
    inAddFunctionPointer(CUST_GET_BASE_AMOUNT, inCustGetBaseAmount);
    inAddFunctionPointer(CUST_COMPUTE_DISPLAY_TOTAL, inCustComputeAndDispTotal);
    inAddFunctionPointer(CUST_GET_TIP, inCustGetTip);
    //  inAddFunctionPointer( CUST_DISPLAY_AT_INIT, inCustDisplayAtInit);
    inAddFunctionPointer(CUST_LOGO_DISPLAY, inCustomDisplayLogo);
    inAddFunctionPointer(CPAC_GET_AUTH_CODE, inCPACGetAuthCode);
    inAddFunctionPointer(CPAC_CONFIRM_INVAMT, inCPACConfirmInvAmt);
    inAddFunctionPointer(CPAC_USER_CHOICE, inCPACUserChoice);
    inAddFunctionPointer(CPAC_TOT_AMT_ALWD, inCPACTotTransAmtAlwd);
    inAddFunctionPointer(CPAC_TOT_AMT_UPDATE, inCPACTotTransAmtUpdate);
    inAddFunctionPointer(CPAC_EDIT_TABLE, inEditCPACTableOperation);
    inAddFunctionPointer(CPAC_GET_USR_INV_NUM, inCPACGetUserInvNum);
    inAddFunctionPointer(CPAC_DEMO_TRAIN, inCPACDemoTrainOperation);        //leo_may0800
    //  inAddFunctionPointer( CPAC_RANGE_NULL, inCPACRange);
    inAddFunctionPointer(CPAC_BATCHCLEAR, inCPACBatchClearOperation);       //leo_may1800
    inAddFunctionPointer(CPAC_LOAD_CUST_CPAC, inLoadCPACRecForPowerFail);
    inAddFunctionPointer(CPAC_CHK_LONG_AMT_OVERFLOW, inCPACCheckLongAmtOverflow);
    inAddFunctionPointer(CITI_USER_CHOICE, inCITIUserChoice);
    inAddFunctionPointer(CITI_PRINT_RECEIPT, inCITIFlowPrintReceipt);
    inAddFunctionPointer(CPAC_LOAD_MISSING_TABLE_FOR_PWRFAIL, inCPACLoadMissingTable);
    inAddFunctionPointer(CPAC_GET_CHECK_MID, inCPACGetCheckMID);
    inAddFunctionPointer(CPAC_GET_MERCH_ENABLE, inCPACGetMerchEnable);      //   Saritha_b1
    inAddFunctionPointer(CPAC_AUTO_SETTLEMENT, inCPACAutoSettleOperation);  //   Saritha_b1
    inAddFunctionPointer(CPAC_KEY_FUNC_2, inCPACKeyFunc2);                  //   Saritha_b1
    inAddFunctionPointer(CPAC_SET_SG_SETTLE_CODE, inCPACSetSettleCode);     //   Saritha_b1
    inAddFunctionPointer(CPAC_SET_AUTO_HANDLE, inCPACSetAutoHandle);        //   Saritha_b1
    inAddFunctionPointer(CPAC_SETTLE_A_HOST, inCPACSettleAHost);                // This ID is used in PFR Flow.
    inAddFunctionPointer(INIT_DAILY_PAYMENT, inDailyPayment);                   //   Saritha_b1
    inAddFunctionPointer(CPAC_DAILY_PAYMENT, inCPACDailyPayment);           //   Saritha_b1
    inAddFunctionPointer(CPAC_SET_MUST_SETTLE_FLAG, inCPACSetMustSettleFlag); // Saritha_b1
    inAddFunctionPointer(CPAC_REPRINT_LAST_RECEIPT, inCPACReprintLastReceiptOperation); // Saritha_b1
    inAddFunctionPointer(CPAC_TRANS_NAME_DISP, inCPACTransNameDisplay); // Saritha_b1
    inAddFunctionPointer(CPAC_DISPLAY_RESPONSE, inCPACDisplayResponse);  //  Saritha_b1
    inAddFunctionPointer(CPAC_PRINT_LINE_FEED, inCPACPrintLineFeed);
    inAddFunctionPointer(CPAC_TIP_PERCENT_VALIDATION, (PFI_TO) inCPACTipPercentValid);
    inAddFunctionPointer(CPAC_PFR_DISPLAY_TRANS_NAME, inCPACDispTransName);
    inAddFunctionPointer(CPAC_FORMATER_CLOSE_HANDLE, inCPACCloseFormaterHandle);
    inAddFunctionPointer(CPAC_VALIDATE_VOID, inCPACValidateVoid);
    inAddFunctionPointer(CPAC_VALIDATE_ADJUST, inCPACValidateAdjust);

#ifdef CITI_PHIL
    inAddFunctionPointer(CITI_OPEN_TAB_RETREIVE_INV_NUM, inCITIOpenTabRetrieveInv);
    inAddFunctionPointer(PHIL_CITI_USER_CHOICE, inPhilUserChoice);
#endif

    inAddFunctionPointer(CITI_IND_CHECK_BATCH_TOTALS, inCITICheckBatchTotals);
    inAddFunctionPointer(CITI_IND_GET_BATCH_NUM_AND_CHECK, inCITIGetBatchNumAndCheck);
    inAddFunctionPointer(CPAC_CLEAR_LAST_RECEIPT_FILE, inRemoveLastRecieptFile);
    inAddFunctionPointer(CHECK_MULTI_BATCH_EMPTY, inCheckMultiBatchEmpty);
    inAddFunctionPointer(DELETE_SINGLE_BATCH, inSingleBatchClearOperation);
    inAddFunctionPointer(CPAC_SHOW_MEMORY_LEFT, inCPACShowMemoryLeftOperation);  //1.4
    inAddFunctionPointer(CPAC_REPRINT_ANY_RECEIPT, inCPACReprintAnyReceiptOperation);

#ifdef CITI_PHIL
    inAddFunctionPointer(CPAC_SETTLEMENT, inCPACSettleOperation);
#endif /*CITI_PHIL */

#ifdef CITI_IND
    inAddFunctionPointer(CITI_GET_BATCH_NUM, inCITIGetBatchNumber);
    inAddFunctionPointer(CITI_GET_SETT_DATE, inCITIGetSettDate);
    inAddFunctionPointer(CITI_AIRLINE_CODE, inGetAirlineCode);
#endif /* CITI_IND */

#ifdef CPACCLRK_C
    inAddFunctionPointer(CPAC_GET_CLERK_ID, inCPACGetClerkID);
    inAddFunctionPointer(CPAC_LOGIN_OPERATION, inCPACLogInOperation);
    inAddFunctionPointer(CPAC_INIT_LOGIN_OPERATION, inCPACInitLogInOperation);
#endif  /* CPACCLRK_C */
    inAddFunctionPointer(SET_TO_MAIN_MENU, inSetToMainMenu);
    inAddFunctionPointer(RENAME_REVERSAL_FILE, inCPACRenameReversalFile);
    inAddFunctionPointer(CPAC_LOAD_VOID_ISSUE_NUMBER, inCPACLoadVoidIssueNumber);

    inAddFunctionPointer(CPAC_CLEAR_CHOLDER, inClearCHolder);
    inAddFunctionPointer(CPAC_CLEAR_ERRMSG, inClearErrorMsg);
    inAddFunctionPointer(EDIT_CST, inEditCSTOperation);
    inAddFunctionPointer(EDIT_LCT, inEditLCTOperation);

    inAddFunctionPointer(CPAC_CLEAR_ADVICE, inCPACClearAdvice);
    inAddFunctionPointer(CPAC_CHK_INV_NUM, inCPACCheckValidInvNum);
    inAddFunctionPointer(CPAC_REMEMBER_HOST_SELECTED, inCPACStoreSelectedHostIndex);

    // #ifdef TLFB   (Made this feature as the part of CPAC Base Application)
    inAddFunctionPointer(CPAC_REPRINT_SETT_REPORT, inCPACCallReprintSettleReport);
    // #endif  /*  TLFB */   (Made this feature as the part of CPAC Base Application)
    inAddFunctionPointer(CPAC_REVERSAL_CLEAR, inCPACClearReversal);
    inAddFunctionPointer(CPAC_RESTART_24DAYS, inCPACRestartAfter24Days);
    inAddFunctionPointer(CPAC_PRINT_PACKET_LOG, inCPACPrintPacketLog);

    inOverloadFieldID(DISPLAY_SWIPE_CARD_INFO, inCustDisplaySwipeCardInfo);
    inOverloadFieldID(DISPLAY_CARD_TITLE, inCPACDisplayCardTitle);
    inOverloadFieldID(START_CARD_TRAN, inCPACStartCardTxn);
    inOverloadFieldID(ABOUT_FILE_PROCESSING, inCPACAboutFileProcessing);
    inOverloadFieldID(MANUAL_ENTRY_PROCESS, (PFI_TO) inCPACManualEntryProcess);
    inOverloadFieldID(CARD_READ_OPERATION, (PFI_TO) inCPACCardReadOperation);
    inOverloadFieldID(DISPLAY_REVIEW_REC, inCPACDefaultDisplayReviewRec);
    inOverloadFieldID(VALIDATE_SWIPED_CARD, inCPACValidateSwipedCard);
    inOverloadFieldID(UPDATE_ACCUM_VALUES, (PFI_TO) inUpdateOfflineAccum);
    inOverloadFieldID(DEMO_FUNCTION, inCPACDemo);



#ifdef HKGM
    inOverloadFieldID(BATCH_REVIEW_TIP_ADJUST, inHKGMBatchReviewTipAdjust);
#endif /* HKGM */
}




/*********************************************************************************************
* @func int | inSetCPACTransFields |
* This routine takes care of loading the Host Specific BitMap
* corresponding to the Transaction that is passed as input to
* this routine.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @parm int | host |
*       This is the host ???.
*
* @parm int | inTransCode |
*       This is the inTransCode ???.
*
* @parm char * | szProcCode |
*       This is the szProcCode ???.
*
* @rdesc Returns the success.
* @flag int | VS_SUCCESS
* @end
**********************************************************************************************/
int inSetCPACTransFields(TRANSACTION_OBJECT* pobTran,int host,unsigned int inTransCode,char* szProcCode) {
#ifndef IMAM_REMOVE
    short inTranCode;
    char szTrackPriority[TRACKS_ALLOWED + 1];//1.4
    char chTrackNum;
    /* Get the transaction type from the GDS */
    inTranCode = pobTran->srBRec.inCode;
    if ((inTransCode != 0x1500) && (inTransCode != 0x1600) && (pobTran->srBRec.inCode != BATCH_UPLOAD))
        memcpy(srISO.pszField03, szProcCode, PROC_CODE_SIZE);
    /* Set the optional bit map fields */
    memset(stOptionalMap, 0, BIT_MAP_SIZE);

	if ((inTranCode != LOGON) &&  (inTranCode != TEST) && (inTranCode != CLS_BATCH) &&  (inTranCode != CLS_BATCH_UPLOAD))  {
		if (pobTran->srBRec.fManual == VS_TRUE ||
			pobTran->srBKey.fVoided == VS_TRUE ||
			pobTran->srTRTRec.TransactionCode == SALE_OFFLINE ||
			pobTran->srTRTRec.TransactionCode == ADJUST ||
			pobTran->srTRTRec.TransactionCode == REFUND_OFFLINE||
			pobTran->srTRTRec.TransactionCode == CPAC_PHIL_ADJUST ||      //1.4_citiphil_don_26feb
			pobTran->srTRTRec.TransactionCode == TIP_ADJUST ||
			pobTran->srTRTRec.TransactionCode == ADD_TIP_OFFLINE ||
			inTranCode == BATCH_UPLOAD ||
			pobTran->srTRTRec.TransactionCode == PRE_COMP)  { // 1.4_dk23
            map_set(stOptionalMap, 2);
            map_set(stOptionalMap, 14);
            map_reset(stOptionalMap, 35);            /* CPAC_UNBKL added */
        } else {
            strcpy(szTrackPriority, szGetTracks());
            chTrackNum = *(strpbrk(szTrackPriority, "123"));                                //1.4
            switch (chTrackNum) {
                //1.4
            case TRACK_ONE:
                map_set(stOptionalMap, 45);
                break;
            case TRACK_TWO:
                map_set(stOptionalMap, 35);
                break;
            default:
                if (strlen(pobTran->srBRec.stT2Data) < 1)
                    map_set(stOptionalMap, 45);
                else
                    map_set(stOptionalMap, 35);
            }
            if (inGetTipProcessing() > TIP_OFF)
                map_set(stOptionalMap, 54);
        }

	#ifdef VXEMVAPP
     if((pobTran->srBRec.inChipStatus == EMV_CARD) &&
     	 ((pobTran->srTRTRec.TransactionCode == SALE) ||
     	 (pobTran->srTRTRec.TransactionCode == SALE_OFFLINE) ||
     	 (pobTran->srTRTRec.TransactionCode == AUTH_ONLY) ||
		 (pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) ||
     	 (pobTran->srTRTRec.TransactionCode == REFUND) ||
     	 (pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||
     	 (pobTran->srBRec.inCode == BATCH_UPLOAD)

     	 /*
     	 (pobTran->srTRTRec.TransactionCode == CASH_ADV) ||
     	 (pobTran->srTRTRec.TransactionCode == PRE_COMP)
     	 */
     	 ))
     		map_set(stOptionalMap, 55);
	#endif /* VXEMVAPP */
    }
    vdGetCPACTPDU((char *) tpdu);
#endif //IMAM_REMOVE
    return(VS_SUCCESS);
}



/*********************************************************************************************
* @func int | inCPACPIPDeinitialize |
*       Function for the PACKET_OBJECT structure. Empty function but required by protocol
*       engine.
*
* @parm PACKET_OBJECT * | pobPacket
*       Packet object
*
* @rdesc return values.
* @flag int | VS_SUCCESS
* @end
**********************************************************************************************/

int inCPACPIPDeinitialize(PACKET_OBJECT* pobPacket)
{
	//For EMV data
	      #ifdef VXEMVAPP
	       field_struct srField55ISOFDT;
	       unsigned char szField55[FIELD55_SIZE + 1];
      #endif /* VXEMVAPP */

    /** /pdebug(("--inCPACPIPDeinitialize--"));*/

    #ifdef VXEMVAPP
		srField55ISOFDT.field_num = 55;
		srField55ISOFDT.packet_sz = FIELD55_SIZE;
		srField55ISOFDT.convert_idx = AV3_STR;
		srField55ISOFDT.reference = szField55;
		srField55ISOFDT.var_sz = FIELD55_SIZE + 1;

		vdOverLoadISOFDT(FIELD55_POSITION, &srField55ISOFDT );
       #endif /* VXEMVAPP */

    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func void | vdInitializeCPAC |
*       Initializes the packet structure function pointers with CPAC functions.
*
* @parm PACKET_OBJECT * | pobPacket
*       Packet object
*
* @end
**********************************************************************************************/

void vdInitializeCPAC(PACKET_OBJECT* pobPacket) {
    pobPacket->inInitialize = (PFI_VD) inCPACInit;
    pobPacket->inAnalyse = (PFI_VD) inCPACPIPAnalyse;
    pobPacket->inDeinitialize = (PFI_VD) inCPACPIPDeinitialize;
}

/*********************************************************************************************
* @func int | inSendReceiveCPAC|
* Creates Host structure and the transaction code then calls pip_trans() which is the
* PIP engine function that controls the packet building and communication. Once the
* pip_trans returns, either the error is processed or advice transactions are sent and
* the response is processed.
*
* Modified - (Loxbit Thailand to incorporate reversal updations with current STAN
* 23/Feb/2002 -Loxbit Bangkok
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc Returns the PIP Engine error code.
* @flag int | VS_ERR
* @flag int | VS_SUCCESS
* @end
* @end
**********************************************************************************************/

int inSendReceiveCPAC(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
#ifndef IMAM_REMOVE
	char szLog[60 + 1];
    int inRetVal;
    short shTransCode,
    shPIPTransCode;
    field_struct* fld_2;
    TRANSACTION_OBJECT* pobTran;
    //  HOST_8583_DATA  my_host_struct;
    //  char szRevFileName[FILENAME_SIZE +1];
    /**/pdebug(("--inSendReceiveCPACPIP--"));/**/
    pobTran = (TRANSACTION_OBJECT *) pobPacket->Transaction;
    pobPacket->inError = 0;                                                 /* Initialize error */
#ifdef UPDATE_REV_STAN    /*   Saritha_b1 changed from TLFB to UPDATE_REV_STAN */

    //inCPACModifyReversal (pobTran, psrHostData);

    /*  Saritha_b1..........Start........Fix for Comm Error during Tip Adjust..... */

    if (!(pobTran->srTRTRec.Offline))
        if (fGetCPACStanInc()) // Making it host specific
            inCPACModifyReversal(pobTran);  // Update the reversal with the current STAN

    /*  Saritha_b1..........End........Fix for Comm Error during Tip Adjust..... */

    pobTran->srBRec.lnSTAN = lnGetSTAN(); // gets the STAN from the MHT, latest STAN

#endif /* UPDATE_REV_STAN       Saritha_b1 changed from TLFB_LOXBIT  to UPDATE_REV_STAN */

    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("No Memory: SendReceiveCPAC 00");
        return(VS_ERR);
    }

    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_TRUE)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("No Memory: SendReceiveCPAC 01");
        vdFreeISO8583Data(psrHostData);
        return(VS_ERR);
    }

	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
    /* Added for Custom base resp validation CPAC_VALID */

    psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation;
    /* Added for Custom base resp validation CPAC_VALID */
    /* Set the reversal flag ON based on the transaction type */
    psrHostData->reverse_flag = (unsigned char) fGetReversal(pobTran);
    /*  vdGetReversalFileName((char *)stRevFileName, inGetCDTHostIndex()); */
    vdGetReversalFileName((char *) stRevFileName, inGetHostHandle());
    shTransCode = shVerifyCPACTransType(pobTran);                               /* Store our update GGCode value so that set_trans_fields() can use it */
    inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *) &shTransCode, 2);

    if ((shPIPTransCode = shLoadPIPTransCode(shTransCode)) == VS_ERR) {
        vdFreeISO8583Data(psrHostData);
        ACTIVITY_LOG("No Memory: SendReceiveCPAC 02");
        return (VS_ERR);
    }

    if (inGGCode() == REFUND && fGetOffline(pobTran))
        shPIPTransCode = (int) A_REFUND_OFFLINE ;


    //for making REFUND go as offline for AMEX


    /* Higher byte of inPIPTransCode contains index into the BitMap file.
                Higher byte of inPIPTransCode contains index into the BitMap file.
                Lower byte of inPIPTransCode contains the transaction type for Pip
                Processing */

    errno = 0;
#ifdef CITI_IND
    //  if (inPIPTransCode == 8213) inPIPTransCode = 3604;  //leo_aug700 added !!
#endif /* CITI_IND*/                                                            // To make Void of a Refund acceptable to pip_trans!!
    /* if (inPIPTransCode == 0x0e14) inPIPTransCode = 0x0d14;   */

    inRetVal = pip_trans((int) shPIPTransCode, psrHostData);

    /* pdebug(("pip_trans Ret=%d",inRetVal));*/
    /* pdebug(("errno=%d fn_8583=%d",errno, fn_8583));*/
    if (inRetVal != PIP_APPROVAL) {
        vdCPACError(pobProtocol, pobPacket, inRetVal);
        LOG_PRINTFF((0x8L, "NOT PIP APPROVAL"));
        sprintf(szLog, "%s  %d ", "Pip Trans:inSendReceiveCPAC03", errno);
        ACTIVITY_LOG(szLog);

		//Start...To fix the AMEX reversal problem where 16 digit PAN was going in reversal request for AMEX
		while( psrHostData->c8583_data->p_fld_table->field_num != 2)
			psrHostData->c8583_data->p_fld_table++;
		fld_2 = psrHostData->c8583_data->p_fld_table;
		memset(fld_2->reference, 0x00, fld_2->var_sz);
		//End...To fix the AMEX reversal problem where 16 digit PAN was going in reversal request for AMEX

        vdFreeISO8583Data(psrHostData);
        return(pobPacket->inError);
    }

    //inRetVal = HOST_ERROR;
    //vdCPACError(pobProtocol, pobPacket, inRetVal);

    if (pobTran->srBRec.inCode == PRE_AUTH && pobTran->srBKey.fOffline) {
        vdCPACDeleteTabAdvice(psrHostData);
        vdSetCPACOpenTabOffline(&pobTran->srBRec, VS_TRUE);
    }

	//Start...To fix the AMEX reversal problem where 16 digit PAN was going in reversal request for AMEX
		while( psrHostData->c8583_data->p_fld_table->field_num != 2)
			psrHostData->c8583_data->p_fld_table++;
		fld_2 = psrHostData->c8583_data->p_fld_table;
		memset(fld_2->reference, 0x00, fld_2->var_sz);
	//End...To fix the AMEX reversal problem where 16 digit PAN was going in reversal request for AMEX

    vdFreeISO8583Data(psrHostData);
#endif //IMAM_REMOVE
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func short  | shVerifyCPACTransType |
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @rdesc Returns the success.
* @flag int | PIP Engine Return Value for the last uploaded host.
* @flag int | VS_ERR
* @end
**********************************************************************************************/
short shVerifyCPACTransType(TRANSACTION_OBJECT* pobTran) {
    short shTransCode;
    VS_BOOL fOpenTabOffline = fGetCPACOpenTabOffline(&pobTran->srBRec);


    if (pobTran->fFloorLimit)                                           /* Is this offline because of floorlimit? */
        shTransCode = SALE_OFFLINE;
    else/* If Close Tab card number different than Open Tab, send Close Tab as
    * On-line sale transaction.
    */ if (pobTran->srBRec.fCloseTabNewCard)
        shTransCode = SALE;
    else
        shTransCode = inGGCode();

    if (pobTran->srBKey.fVoided) {
        if (shTransCode == CASH_ADV)
            shTransCode = VOID_CASH_ADV;
        else if (pobTran->srBRec.inType == DEBIT_TRAN) {
            if (fGetOffline(pobTran)) {
                shTransCode = VOID_SALE_OFFLINE;
                /* clrscr(); vdDisplayAt(1,1,"VOID_SALE_OFFLN", CLR_EOL); */
            } else
                shTransCode = VOID;
        } else {
            if (fGetOffline(pobTran))
                shTransCode = VOID_REFUND_OFFLINE;
            else
                shTransCode = VOID_REFUND;
        }
    } else if ((pobTran->fAdjust) || (pobTran->fOtherAdjust)) {
        if (pobTran->srBRec.inType == DEBIT_TRAN)
            shTransCode = SALE_ADJST;
        else if (fGetOffline(pobTran))
            shTransCode = ADJUST_REFUND_OFFLINE;
        else
            shTransCode = RET_ADJST;
    } else if (pobTran->fTipAdjust) {
        if (pobTran->srBRec.inType == DEBIT_TRAN)
            shTransCode = ADD_TIP_OFFLINE;
        else if (fGetOffline(pobTran))
            shTransCode = ADJUST_REFUND_OFFLINE;
        else
            shTransCode = RET_ADJST;
    } else if (fGetOffline(pobTran) && shTransCode == SALE)
        shTransCode = SALE_OFFLINE;

	#ifdef ICICI
		if (fGetOffline(pobTran) && shTransCode == REFUND)
			shTransCode = REFUND_OFFLINE;		/*REFUND OFFLINE/ONLINE */
	#endif  /* ICICI   */
																			/*
       															  			  *       We are checking below for the condition where the Open Tab was approved
																			  *       through Voice Auth Processing, this means we are generating an original
																			  *       Advice and Not Adjusting an existing transaction. (Transactions appproved
																			  *       through Voice Auth Processing Do Not Generate an Advice).
																			  */
    else if (pobTran->srBRec.fCloseTabSameCard && fOpenTabOffline)
        shTransCode = SALE_OFFLINE;
    /** /pdebug(("VerifyPIP%d",inTransCode));*/
    return(shTransCode);
}

/*********************************************************************************************
* @func void | vdLoadCPACParams |
* Load the Network Internation ID  - ISO Field # 24
*
* @parm CPAC_REC * | psrCPACRec |
*       CPAC Host data record
*
* @end
**********************************************************************************************/

void vdLoadCPACParams(CPAC_REC* psrCPAC) {
    char szHostName[30];
    short inMerchantNum;

    memset(szHostName, 0, sizeof(szHostName));
    strcpy(szHostName, szGetHostFileName());  //CPAC2.1B
    strcat(szHostName, ".dat");
    inMerchantNum = inGetMerchantNum() - 1;//CPAC2.1B

    if (inLoadConfRec(szHostName, SIZE_CPAC_REC, inMerchantNum, (char *) psrCPAC) != VS_SUCCESS)
        vdDisplayMessageFromFile(HFT_ERR_MSG, ERROR_MSG);
}

void vdGetCPACTPDU(char* pchTPDU) {
    CPAC_REC srCPAC;

    vdLoadCPACParams(&srCPAC);
    strlcpy(pchTPDU, srCPAC.szCPACTPDU, TPDU_SIZE);
}


/*********************************************************************************************
* @func void | vdLoadCPACField04 |
* Load the Transaction Amount - ISO Field # 4
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField04(TRANSACTION_OBJECT* pobTran) {
    short inTranCode,
    inPercentOver,
    inRepeat;
    long lnTransactionAmt;

    if (fGetOffline(pobTran))
        inPercentOver = 0;
    else
        inPercentOver = inGetPerOver();

    inTranCode = pobTran->srBRec.inCode;

    do {
        inRepeat = VS_FALSE;

        switch (inTranCode) {
        case SALE:
            lnTransactionAmt = pobTran->srBKey.lnTotalOfTransactionAmount;

            if (fComputeOverage(pobTran))
                lnTransactionAmt += (inPercentOver * pobTran->srBKey.lnTotalOfTransactionAmount / 100L);

			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField04, SUBSTITUTE_LD, lnTransactionAmt);
				} else {
					sprintf((char *)srISO.pszField04, "%ld00", lnTransactionAmt); 
				}
			}
            break;
        case BATCH_UPLOAD:
            inTranCode = pobTran->srBRec.inOrgCode;

            if (inTranCode == VOID)
                strcpy((char *) srISO.pszField04, TWELVE_ZEROS);

#ifdef CITI_IND
            if ((inTranCode == VOID) || (inTranCode == VOID_REFUND) || (inTranCode == VOID_REFUND_OFFLINE))
                strcpy((char *) srISO.pszField04, TWELVE_ZEROS); //leo_nov2800
#endif /*CITI_IND*/
            inPercentOver = 0;
            inRepeat = VS_TRUE;            /* CPAC_UNBKL added */
            break;
        case CHECK_TRAN:
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *) srISO.pszField04, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
				} else {
					sprintf((char *) srISO.pszField04, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
				}
			}
            break;
        default:
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *) srISO.pszField04, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
				} else {
					sprintf((char *) srISO.pszField04, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
				}
			}
            break;
        }
    } while (inRepeat);                             /* CPAC_UNBKL added */

#ifndef CITI_IND

    if (((pobTran->srTRTRec.TransactionCode) == VOID) && ((pobTran->srTRTRec.Offline) == VS_TRUE)) {
		{ // Amount - Currency Adjust
			if (inGetCurrencyIdx()) {
				sprintf((char *) srISO.pszField04, SUBSTITUTE_LD, 0L);
			} else {
				sprintf((char *) srISO.pszField04, "%ld00", 0L);
			}
		}
        map_set(stOptionalMap, 60);
    }

#endif /*CITI_IND*/
#ifdef CITI_IND

    if (((pobTran->srTRTRec.TransactionCode) == VOID_SALE_OFFLINE) || ((pobTran->srTRTRec.TransactionCode) == VOID) || ((pobTran->srTRTRec.TransactionCode) == VOID_REFUND)) {
		{ // Amount - Currency Adjust
			if (inGetCurrencyIdx()) {
				sprintf((char *) srISO.pszField04, SUBSTITUTE_LD, 0L);
			} else {
				sprintf((char *) srISO.pszField04, "%ld00", 0L);
			}
		}
        map_set(stOptionalMap, 60);
    }

    if (inGetCVV2Type() == NO_CVV2 || (pobTran->srBRec.fManual == VS_FALSE) || pobTran->srBKey.fOffline)
        map_reset(stOptionalMap, 48);

    if ((inGetCVV2Type() == CVV2_CARD_NOT_PRESENT) && fGetCardPresent() && pobTran->fCardPresent)
        map_reset(stOptionalMap, 48);

    if ((inGetCVV2Type() == CVV2_CARD_NOT_PRESENT) && (fGetCardPresent() == VS_FALSE))
        map_reset(stOptionalMap, 48);
    else
        map_set(stOptionalMap, 48);
#endif /*CITI_IND*/

    if (pobTran->srBRec.lnTipAmount != 0L)       /* Added by Lenin 06/06/2000 to disable if tip amount is zero */
        map_set(stOptionalMap, 54);

	if (pobTran->srBRec.inCode == BATCH_UPLOAD){
		LOG_PRINTFF((0x08L, "BATCH UPLOAD TIP ADJUSTED"));
		lnTransactionAmt = pobTran->srBKey.lnTotalOfTransactionAmount;
		{ // Amount - Currency Adjust
			if (inGetCurrencyIdx()) {
				sprintf((char *)srISO.pszField04, SUBSTITUTE_LD, lnTransactionAmt);
			} else {
				sprintf((char *)srISO.pszField04, "%ld00", lnTransactionAmt); 
			}
		}
	}
	LOG_PRINTFF((0x08L, "LIEM ==> srISO.pszField04=[%s]", (char *)srISO.pszField04));
}

/*********************************************************************************************
* @func void | vdLoadCPACField14 |
* Load Expiration Date - ISO Field # 14
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField14(TRANSACTION_OBJECT* pobTran) {
    char szDate[DATE_SIZE + 1];
    //char    szTempYear[2]; CPAC_LINT_RMD

    strlcpy(szDate, pobTran->srBRec.szExpDate, EXP_DATE_SIZE);
    //strlcpy (szTempYear, szDate, 2);
    //strlcpy (szDate, szDate+2, 2);
    //strlcpy (szDate+2,szTempYear, 2);
    strlcpy((char *) srISO.pszField14, szDate, EXP_DATE_SIZE);
}

/*********************************************************************************************
* @func void | vdLoadCPACField22 |
* Load the POS Entry Mode - ISO Field # 22
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
* This function was added because of the specific requirement of different POS Entry Codes for Credit
* Swipe/Manual entry for CitiBank India.
* @end
**********************************************************************************************/

void vdLoadCPACField22(TRANSACTION_OBJECT* pobTran) {
#ifndef CITI_IND
    if (pobTran->srBRec.inTranCardType == DEBIT_CARD) {
        if (pobTran->srBRec.fManual == VS_TRUE)
            strlcpy((char *) srISO.pszField22, MANUAL_POS_DEBIT_ENTRY_CODE, POS_EM_SIZE);
        else
            strlcpy((char *) srISO.pszField22, SWIPE_POS_DEBIT_ENTRY_CODE, POS_EM_SIZE);
    } else {
        if (pobTran->srBRec.fManual == VS_TRUE)
            strlcpy((char *) srISO.pszField22, MANUAL_POS_ENTRY_CODE, POS_EM_SIZE);
        else
            //strlcpy((char *) srISO.pszField22, SWIPE_POS_ENTRY_CODE, POS_EM_SIZE);
			strlcpy((char *) srISO.pszField22, SWIPE_POS_ENTRY_CODE_NON_EMV, POS_EM_SIZE); // for compability with non-emv host
    }

#else /* CITI_IND */
	???
    if (pobTran->srBRec.inTranCardType == DEBIT_CARD) {
        if (pobTran->srBRec.fManual == VS_TRUE)
            strlcpy((char *) srISO.pszField22, MANUAL_POS_DEBIT_ENTRY_CODE, POS_EM_SIZE);
        else
            strlcpy((char *) srISO.pszField22, SWIPE_POS_DEBIT_ENTRY_CODE, POS_EM_SIZE);
    } else {
        if (pobTran->srBRec.fManual == VS_TRUE)
            strlcpy((char *) srISO.pszField22, MANUAL_CITI_IND_POS_ENTRY_CODE, POS_EM_SIZE);
        else
            strlcpy((char *) srISO.pszField22, SWIPE_CITI_IND_POS_ENTRY_CODE, POS_EM_SIZE);
    }
#endif /*CITI_IND*/
}
/*********************************************************************************************
* @func void | vdLoadCPACField24 |
* Load the Network Internation ID  - ISO Field # 24
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField24(TRANSACTION_OBJECT* pobTran) {
    CPAC_REC srCPAC;
    vdLoadCPACParams(&srCPAC);
    /* Needs to be added from the Amex PIP data record */
    vdGetCPACNII((char *) srISO.pszField24);
    return;
}

/*********************************************************************************************
* @func void | vdLoadCPACField41 |
* Load Terminal ID - ISO Field # 41
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField41(TRANSACTION_OBJECT* pobTran) {
    CPAC_REC srCPAC;

    vdLoadCPACParams(&srCPAC);
    vdGetCPACTermID((char *) srISO.pszField41);
}

/*********************************************************************************************
* @func void | vdLoadCPACField37 |
* Load Retrieval Reference number - ISO Field # 37
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField37(TRANSACTION_OBJECT* pobTran) {
    vdGetCPACRetRefNum(&pobTran->srBRec, srISO.pszField37);
}

/*********************************************************************************************
* @func void | vdLoadCPACField39 |
* Load Retrieval Reference number - ISO Field # 37
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField39(TRANSACTION_OBJECT* pobTran) {
    memcpy((char *) srISO.pszField39, pobTran->srBRec.szRespCode, 2); /* Response Code to Batch */
    srISO.pszField39[2] = 0x00;  // CPAC_LINT changed strcpy to memcpy
}       /* CPAC_UNBK changed RESP_CODE_SIZE - 1  -> 2 */


/*********************************************************************************************
* @func void | vdLoadCPACField42 |
* Load Merchant ID - ISO Field # 42
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField42(TRANSACTION_OBJECT* pobTran) {
    CPAC_REC srCPAC;

    vdLoadCPACParams(&srCPAC);

    vdGetCPACMerchID((char *) srISO.pszField42);
}
#ifdef CITI_IND
/*********************************************************************************************
* @func void | vdLoadCPACField48 |
* Load Merchant ID - ISO Field # 48
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/
void vdLoadCPACField48(TRANSACTION_OBJECT* pobTran) {
    //sprintf((char *)srISO.pszField48, "%s", );//1.4 LENIN
    if ((inGetCVV2Type() == CVV2_CARD_NOT_PRESENT) && (fGetCardPresent() == VS_FALSE))
        return;
    else {
        // map_set(stOptionalMap, 48);
        strlcpy((char *) srISO.pszField48, pobTran->szCVV2Value, CVV2_SIZE);
        return;
    }

    // return;
}


#endif /* CITI_IND */

void vdLoadCPACField52(TRANSACTION_OBJECT *pobTran) 
{
    if ( pobTran->srBRec.inTranCardType == DEBIT_CARD || inGetType() == DEBIT_CARD) {
		LOG_PRINTFF((0x08L, "F52 Filled"));
	    SVC_DSP_2_HEX((char *)pobTran->szPIN, (char *)srISO.pszField52, 8);
	
    }
}
/*********************************************************************************************
* @func void | vdLoadCPACField54 |
* Load the additional amount field - ISO Field # 54
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end

**********************************************************************************************/

void vdLoadCPACField54(TRANSACTION_OBJECT* pobTran) {
    //char    szScratch[25];   CPAC_LINT_REMOVED
    VS_BOOL fIncludeTipField = VS_FALSE;

    /** /pdebug (("---in Load Field 54---"));*/
    /*    if (pobTran->srBKey.fVoided   || ( atol ((char *)srISO.pszField54) == 0L)) CPAC_UNBKL removed & added the following */
    if (pobTran->srBKey.fVoided || (pobTran->srBRec.lnTipAmount == 0L))
        map_reset(stOptionalMap, 54);
    else {
        if ((pobTran->fTipAdjust) && !pobTran->srBKey.fUploaded && pobTran->srBRec.fTipEntered)
            fIncludeTipField = VS_TRUE;
		{ // Amount - Currency Adjust
			if (inGetCurrencyIdx()) {
				sprintf((char *) srISO.pszField54, SUBSTITUTE_LD, pobTran->srBRec.lnTipAmount);
			} else {
				sprintf((char *) srISO.pszField54, "%ld00", pobTran->srBRec.lnTipAmount);
			}
		}
    }

    if (atol((char *) srISO.pszField54) == 0L && !fIncludeTipField)
        map_reset(stOptionalMap, 54);
    else
        pad((char *) srISO.pszField54, (char *) srISO.pszField54, '0', ISO_AMT_SIZE, RIGHT);
}

/*********************************************************************************************
* @func void | vdLoadCPACField60 |
* Load the Private Field 60
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField60(TRANSACTION_OBJECT* pobTran) {
    short inTranCode;
    long lnBatchUploadSTAN;

#ifdef ICICI
	#ifndef CITI_IND
    		long lnTotTransAmt;
	#endif /*CITI_IND*/
#endif /* ICICI  */

    char szMsgTypeId[MTI_SIZE + 1];
    //char    szScratch[25]; CPAC_LINT_REMOVED
    unsigned char pszField37[FIELD37_SIZE + 1];  /* CPAC_UNBKL added */


    /** /pdebug(("--vdLoadField60--"));*/

	#ifdef ICICI
	#ifndef CITI_IND
		if ( (pobTran->srTRTRec.TransactionCode == VOID) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND_OFFLINE) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND)) //citi_ind added 2nd condition
    		{
        		//void refund ->void refund offline
        		if (pobTran->srBKey.fUploaded == VS_TRUE)
			{
            			if (inGetTipProcessing())
				{
                			lnTotTransAmt = pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount;
							{ // Amount - Currency Adjust
								if (inGetCurrencyIdx()) {
									sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, lnTotTransAmt);
								} else {
									sprintf((char *) srISO.pszField60, "%ld00", lnTotTransAmt);
								}
							}
				}
				else
							{ // Amount - Currency Adjust
								if (inGetCurrencyIdx()) {
									sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
								} else {
									sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
								}
							}
			}
			else
			{
							{ // Amount - Currency Adjust
								if (inGetCurrencyIdx()) {
									sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
								} else {
									sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
								}
							}
			}
        		pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);                                //citi_ind added line
		}
		if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE ) //citi_ind added 2nd condition
		{																																												//void refund ->void refund offline
			if (pobTran->srBKey.fUploaded == VS_TRUE)
			{
				if (inGetTipProcessing())
				{
					lnTotTransAmt = pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount;
					{ // Amount - Currency Adjust
						if (inGetCurrencyIdx()) {
							sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, lnTotTransAmt);
						} else {
							sprintf((char *)srISO.pszField60, "%ld00", lnTotTransAmt);
						}
					}
				}
				else
					{ // Amount - Currency Adjust
						if (inGetCurrencyIdx()) {
							sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOldTotalTransactionAmount);
						} else {
							sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnOldTotalTransactionAmount);
						}
					}					
			}
			else
			{
				{ // Amount - Currency Adjust
					if (inGetCurrencyIdx()) {
						sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
					} else {
						sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
					}
				}					
			}
			pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);								//citi_ind added line
		}
	#endif /*CITI_IND*/

	#ifdef CITI_IND
    	if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE)
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE)
		{
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount);
				} else {
					sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount);
				}
			}								
		}
		else
		{
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
				} else {
					sprintf((char *) srISO.pszField60, "%ld00", pobTran->srBRec.lnOrigTotalTransactionAmount);
				}
			}											
		}
        	pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);
    	}

    	if ((pobTran->srTRTRec.TransactionCode == VOID) && (pobTran->srTRTRec.Offline == VS_TRUE))
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE)
		{
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount  + pobTran->srBRec.lnTipAmount);
				} else {
					sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount  + pobTran->srBRec.lnTipAmount);
				}
			}														
		}
        	else
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
				} else {
					sprintf((char *) srISO.pszField60, "%ld00", pobTran->srBRec.lnOrigTotalTransactionAmount);
				}
			}														

		pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);
    	}
	#endif /*NOT CITI_IND*/
#else

	#ifdef CITI_IND
	if ((pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE) || (pobTran->srTRTRec.TransactionCode == VOID) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND_OFFLINE) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND)) //citi_ind added 2nd condition
	{																																												//void refund ->void refund offline
		if (pobTran->srBKey.fUploaded == VS_TRUE){
			if (inGetTipProcessing()) {
					lnTotTransAmt = pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount;
					{ // Amount - Currency Adjust
						if (inGetCurrencyIdx()) {
							sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, lnTotTransAmt);
						} else {
							sprintf((char *)srISO.pszField60, "%ld00", lnTotTransAmt);
						}
					}														
			}
			else 
					{ // Amount - Currency Adjust
						if (inGetCurrencyIdx()) {
							sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
						} else {
							sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
						}
					}																	
		}
		else {
				{ // Amount - Currency Adjust
					if (inGetCurrencyIdx()) {
						sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
					} else {
						sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnOrigTotalTransactionAmount);
					}
				}																	
		}

		pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);								//citi_ind added line
	}
#endif /*CITI_IND*/

#ifndef CITI_IND
	if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE)
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE){
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
				} else {
					sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
				}
			}																	
		}
		else {
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
				} else {
					sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnOrigTotalTransactionAmount);
				}
			}																				
		}
        pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);
	}


	if ((pobTran->srTRTRec.TransactionCode == VOID) && (pobTran->srTRTRec.Offline == VS_TRUE))
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE)
		{
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
				} else {
					sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
				}
			}																							
		}
		else
		{
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
				} else {
					sprintf((char *)srISO.pszField60, "%ld00", pobTran->srBRec.lnOrigTotalTransactionAmount);
				}
			}																									
		}
        pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);
	}
#endif /*NOT CITI_IND*/

#endif   /*  ICICI   */
    if (pobTran->srTRTRec.TransactionCode == ADJUST || pobTran->srTRTRec.TransactionCode == CPAC_PHIL_ADJUST ||  /* 1.4_citiphil_don_DSC */
        pobTran->srTRTRec.TransactionCode == SALE_ADJST || pobTran->srTRTRec.TransactionCode == ADD_TIP_OFFLINE || pobTran->srTRTRec.TransactionCode == RET_ADJST || pobTran->srTRTRec.TransactionCode == TIP_ADJUST || pobTran->srTRTRec.TransactionCode == ADJUST_REFUND_OFFLINE || pobTran->srTRTRec.TransactionCode == ADJUST_PHONE_OFFLINE) {
        if (pobTran->srBKey.fUploaded == VS_TRUE)
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
				} else {
					sprintf((char *) srISO.pszField60, "%ld00", pobTran->srBRec.lnBaseTransactionAmount);
				}
			}																									            			
        else
			{ // Amount - Currency Adjust
				if (inGetCurrencyIdx()) {
					sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
				} else {
					sprintf((char *) srISO.pszField60, "%ld00", pobTran->srBRec.lnOrigTotalTransactionAmount);
				}
			}																									            						
        /*CPAC_UNBKL removed to add the following line
        */
        /*      sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);*/
        pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);
    }



    inTranCode = pobTran->srBRec.inCode;

    switch (inTranCode) {
    case CLS_BATCH    :
    case CLS_BATCH_UPLOAD :
        long2str((char *) srISO.pszField60, lnGetBatchNum());
        /*
                    pad((char *)srISO.pszField60, (char *)srISO.pszField60, '0', inGetBatchNumSize(), RIGHT);
                    CPAC_UNBKL  removed to add the following line:: inGetBatchNumSize() => 6
        */
        pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', 6, RIGHT);

        break;
    case BATCH_UPLOAD           :
        /* Load the Original Data Message in field 60 */
        /* Field 60 contains 4 digits of MID, 6 digits of STAN
           and 12 digits of Reserved space set to spaces.
           */
        vdGetCPACMsgTypeId(&pobTran->srBRec, (unsigned char *) szMsgTypeId);
        vdGetCPACRetRefNum(&pobTran->srBRec, pszField37);  /* CPAC_UNBKL added */

        lnBatchUploadSTAN = lnGetCPACBatchUploadSTAN(&pobTran->srBRec);
        /*
                    sprintf((char *) srISO.pszField60, "%02x%02x%06ld", szMsgTypeId[0],
                            szMsgTypeId[1], lnBatchUploadSTAN);
                    CPAC_UNBKL removed to add the following line :: added field 37
        */

	 memset((char *) srISO.pszField60, 0, sizeof((char *) srISO.pszField60));

        sprintf((char *) srISO.pszField60, "%02x%02x%06ld%012s", szMsgTypeId[0], szMsgTypeId[1], lnBatchUploadSTAN, pszField37);

        pad((char *) srISO.pszField60, (char *) srISO.pszField60, ' ', 22, LEFT);
	//jrd SPQALog107
	srISO.pszField60[22]=NULL_CH;


        break;
    default :
        return;
    }
}


/*********************************************************************************************
* @func void | vdLoadCPACField61 |
* Load the Private Field 61
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField61(TRANSACTION_OBJECT* pobTran) {
    CPAC_REC srCPAC;

    vdLoadCPACParams(&srCPAC);
    vdGetCPACDescCode((char *) srISO.pszField61);
    pad((char *) srISO.pszField61, (char *) srISO.pszField61, ' ', PVT_61_SIZE, LEFT);

	if ((pobTran->srTRTRec.TransactionCode == SALE) && 
		(pobTran->srBRec.inInstallments >= 2) && 
		(pobTran->srBRec.inPlan >= 1) && (pobTran->srBRec.inPlan <= 3)) {  // for Installment App BNI
		memset(srISO.pszField61, 0x00, sizeof(srISO.pszField61));
		sprintf((char *)srISO.pszField61, "%03d%02d%07ld00", pobTran->srBRec.inPlan, pobTran->srBRec.inInstallments, pobTran->srBKey.lnTotalOfTransactionAmount);
		pad((char *)srISO.pszField61, (char *)srISO.pszField61, '0', 14, LEFT);
	}	
	if ((pobTran->srTRTRec.TransactionCode == SALE) && 
		(pobTran->srBRec.inInstallments >= 1) && 
		(pobTran->srBRec.inPlan >= 4)) {  // for Online Redemption
		memset(srISO.pszField61, 0x00, sizeof(srISO.pszField61));
		if (pobTran->srBRec.inPlan == 4) { //FULL
			sprintf((char *)srISO.pszField61, "%02d%09ld00%09ld00%09ld00", 
				88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBKey.lnTotalOfTransactionAmount, 0L);
				//88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBRec.lnBaseTransactionAmount, 0L);
				//88, pobTran->srBKey.lnTotalOfTransactionAmount, 0L, 0L);
		} else {
			sprintf((char *)srISO.pszField61, "%02d%09ld00%09ld00%09ld00", 
				88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBRec.lnDualAmount, pobTran->srBKey.lnTotalOfTransactionAmount - pobTran->srBRec.lnDualAmount);
				//88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBRec.lnTipAmount, pobTran->srBRec.lnBaseTransactionAmount-pobTran->srBRec.lnTipAmount);
		}
		pad((char *)srISO.pszField61, (char *)srISO.pszField61, '0', 69-7, LEFT);
		pad((char *)srISO.pszField61, (char *)srISO.pszField61, ' ', 69, LEFT);

		map_reset(stOptionalMap, 54);
		//map_reset(stMap8583, 54);
	}	

	if (pobTran->srTRTRec.TransactionCode == POINT_BAL_INQ) {  // for Online Redemption
		memset(srISO.pszField61, 0x00, sizeof(srISO.pszField61));
		if (pobTran->srBRec.inPlan == 4) { //FULL
			sprintf((char *)srISO.pszField61, "%02d%09ld00%09ld00%09ld00", 
				88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBRec.lnBaseTransactionAmount, 0L);
		} else {
			sprintf((char *)srISO.pszField61, "%02d%09ld00%09ld00%09ld00", 
				88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBRec.lnDualAmount, pobTran->srBKey.lnTotalOfTransactionAmount);
				//88, pobTran->srBKey.lnTotalOfTransactionAmount, pobTran->srBRec.lnTipAmount, pobTran->srBRec.lnBaseTransactionAmount);
		}
		pad((char *)srISO.pszField61, (char *)srISO.pszField61, '0', 69-7, LEFT);
		pad((char *)srISO.pszField61, (char *)srISO.pszField61, ' ', 69, LEFT);

		map_reset(stOptionalMap, 54);
		//map_reset(stMap8583, 54);
	}	
    return;
}

/*********************************************************************************************
* @func void | vdLoadCPACField62 |
* Load the Private Field 62
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField62(TRANSACTION_OBJECT* pobTran) {
    // CPAC_UNBKL Added {
    short inTranCode;

    inTranCode = pobTran->srBRec.inCode;

    if (inTranCode == CLS_BATCH || inTranCode == CLS_BATCH_UPLOAD)
        long2str((char *) srISO.pszField62, lnGetInvNum()); //###### Needs investigation CPAC_?
    else
        long2str((char *) srISO.pszField62, pobTran->srBKey.lnInvNum);

    // CPAC_UNBKL Added }

    pad((char *) srISO.pszField62, (char *) srISO.pszField62, '0', inGetSTANSize(), RIGHT);
    return;
}


/*********************************************************************************************
* @func void | vdLoadCPACField63 |
* Load the Private Field 63
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdLoadCPACField63(TRANSACTION_OBJECT* pobTran) {
    ACCUM_REC srHostTotals ;
    //ACCUM_TOTALS *psrTotals ;   CPAC_LINT_REMOVED
    char szScratch[30];
    double dbSaleAmount;
    double dbRefundAmount;
    long lnSaleCount;
    long lnRefundCount;

    double dbDebitSaleAmount;
    double dbDebitRefundAmount;
    long lnDebitSaleCount;
    long lnDebitRefundCount;
    /** /pdebug(("--vdLoadField63--"));*/
    if ((pobTran->srBRec.inCode==SALE) &&   // for Airline
		(pobTran->srTRTRec.TransactionCode==SALE) &&
		(fGetImamAirlineTrx())){
		memset((char *)srISO.pszField63, 0x00, sizeof(srISO.pszField63));
		if (strlen(pobTran->srBRec.szCustNum)<TICKET_ID_SIZE) 
			strncpy((char *)srISO.pszField63, "0000000000000", TICKET_ID_SIZE - strlen(pobTran->srBRec.szCustNum));
		strcat((char *)srISO.pszField63, pobTran->srBRec.szCustNum);
		return;
   	}

    if ((pobTran->srBRec.inCode != CLS_BATCH) && (pobTran->srBRec.inCode != CLS_BATCH_UPLOAD))
        return;
    if (inGetHostTotals(pobTran, (ACCUM_REC *) &srHostTotals) != VS_SUCCESS)
        return;
/*
    dbRefundAmount = srHostTotals.srTotals[DEBIT_CARD].dbAmount[CREDIT_TRAN] + srHostTotals.srTotals[CREDIT_CARD].dbAmount[CREDIT_TRAN];
    dbSaleAmount = srHostTotals.srTotals[DEBIT_CARD].dbAmount[DEBIT_TRAN] + srHostTotals.srTotals[CREDIT_CARD].dbAmount[DEBIT_TRAN];
    lnRefundCount = srHostTotals.srTotals[DEBIT_CARD].lnCount[CREDIT_TRAN] + srHostTotals.srTotals[CREDIT_CARD].lnCount[CREDIT_TRAN];
    lnSaleCount = srHostTotals.srTotals[DEBIT_CARD].lnCount[DEBIT_TRAN] + srHostTotals.srTotals[CREDIT_CARD].lnCount[DEBIT_TRAN];
*/
	{
    dbDebitRefundAmount = srHostTotals.srTotals[DEBIT_CARD].dbAmount[CREDIT_TRAN];
	dbRefundAmount = srHostTotals.srTotals[CREDIT_CARD].dbAmount[CREDIT_TRAN];
    dbDebitSaleAmount = srHostTotals.srTotals[DEBIT_CARD].dbAmount[DEBIT_TRAN];
	dbSaleAmount = srHostTotals.srTotals[CREDIT_CARD].dbAmount[DEBIT_TRAN];
    lnDebitRefundCount = srHostTotals.srTotals[DEBIT_CARD].lnCount[CREDIT_TRAN];
	lnRefundCount = srHostTotals.srTotals[CREDIT_CARD].lnCount[CREDIT_TRAN];
    lnDebitSaleCount = srHostTotals.srTotals[DEBIT_CARD].lnCount[DEBIT_TRAN];
	lnSaleCount = srHostTotals.srTotals[CREDIT_CARD].lnCount[DEBIT_TRAN];
	}
	{ // Amount - Currency Adjust
		if (inGetCurrencyIdx()) {

		} else {
			dbRefundAmount = dbRefundAmount*100;  
			dbSaleAmount = dbSaleAmount * 100;  
			dbDebitRefundAmount = dbDebitRefundAmount*100;  
			dbDebitSaleAmount = dbDebitSaleAmount * 100;  
		}
	}

#ifndef CITI_IND
    /*    sprintf((char *) srISO.pszField63,"%03d%012.0f%03d%012.0f%060ld",
           (int)lnSaleCount,  dbSaleAmount,
           (int)lnRefundCount, dbRefundAmount, 0L);
    */

    sprintf((char *) srISO.pszField63, "%03d", (int) lnSaleCount);
    vdDb2Str(dbSaleAmount, szScratch);
    vdTrimLeadSpaces(szScratch);
    pad(szScratch, szScratch, '0', 12, RIGHT);
    strcat((char *) srISO.pszField63, szScratch);
    sprintf(szScratch, "%03d", (int) lnRefundCount);
    strcat((char *) srISO.pszField63, szScratch);
    vdDb2Str(dbRefundAmount, szScratch);
    vdTrimLeadSpaces(szScratch);
    pad(szScratch, szScratch, '0', 12, RIGHT);
    strcat((char *) srISO.pszField63, szScratch);

	sprintf(szScratch, "%03d", (int) lnDebitSaleCount);
    strcat((char *) srISO.pszField63, szScratch);
	vdDb2Str(dbDebitSaleAmount, szScratch);
    vdTrimLeadSpaces(szScratch);
    pad(szScratch, szScratch, '0', 12, RIGHT);
    strcat((char *) srISO.pszField63, szScratch);

	sprintf(szScratch, "%03d", (int) lnDebitRefundCount);
    strcat((char *) srISO.pszField63, szScratch);
	vdDb2Str(dbDebitRefundAmount, szScratch);
    vdTrimLeadSpaces(szScratch);
    pad(szScratch, szScratch, '0', 12, RIGHT);
    strcat((char *) srISO.pszField63, szScratch);

    //strcat((char *) srISO.pszField63, "000000");
	//strcat((char*)srISO.pszField63, "000000000000000000000000000000000000000000000000000000"); // : Make it 0090
	pad((char *) srISO.pszField63,(char *) srISO.pszField63,'0', 90, LEFT); //
#endif /* not CITI_IND*/

#ifdef CITI_IND   //We need to restrict the lenght of field 63 to 30 not 90!!!!Citibank India asked
    sprintf((char *) srISO.pszField63, "%03d", (int) lnSaleCount);
    vdDb2Str(dbSaleAmount, szScratch);
    vdTrimLeadSpaces(szScratch);
    pad(szScratch, szScratch, '0', 12, RIGHT);
    strcat((char *) srISO.pszField63, szScratch);
    sprintf(szScratch, "%03d", (int) lnRefundCount);
    strcat((char *) srISO.pszField63, szScratch);
    vdDb2Str(dbRefundAmount, szScratch);
    vdTrimLeadSpaces(szScratch);
    pad(szScratch, szScratch, '0', 12, RIGHT);
    strcat((char *) srISO.pszField63, szScratch);

    /*  sprintf((char *) srISO.pszField63,"%03d%012.0f%03d%012.0f",
           (int)lnSaleCount,  dbSaleAmount,
           (int)lnRefundCount, dbRefundAmount); */
#endif /*CITI_IND*/
}

void vdLoadCPACField64(TRANSACTION_OBJECT *pobTran)  //LIEM, origin from CITISRC
{
	memset((char *)srISO.pszField64, 0x00, sizeof(srISO.pszField64));
	memset((char *)srISO.pszField64, '0', 16);
	LOG_PRINTFF((0x08L, "F64 = %s",(char *)srISO.pszField64));
}


/*********************************************************************************************
* @func int | inGetCPACReceiptFields |
*               Copies the auth code, terminal ID and merchant ID to the receipt
*               structure.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

int inGetCPACReceiptFields(TRANSACTION_OBJECT* pobTran) {
    //    char szScratch[25]; CPAC_LINT_REMOVED
    CPAC_REC srCPAC;
   int istart=0;
   int ilen=0;
char    buff[10];

	char szTID[CPAC_TERM_ID_SIZE+1],szMID[CPAC_MERCH_ID_SIZE+1];
		       memset(buff,0x00,sizeof buff);
    //  char szAuthCode[AUTH_CODE_SIZE]; CPAC_LINT_REMOVED

    pad(srRcpt.unFrm.srReceipt.szApprovalCode, srRcpt.unFrm.srReceipt.szApprovalCode, ' ', AUTH_CODE_SIZE, RIGHT);

    /*
     *      Load Host Fields - Terminal and Merchant IDs
     */
    vdLoadCPACParams(&srCPAC);

#if 1 // imam 	

		  if (srCPAC.fMaskMid)
		  	{ 
		  	       vdGetCPACMerchID(szMID);  
				   memset(buff,0x00,sizeof buff);
				   get_env_x("MIDMASKING", 0, buff);
				   istart=atoi(buff);
				      if  (istart>=14)
				   	istart=0;
				   memset(buff,0x00,sizeof buff);
				   get_env_x("MIDMASKING", 1, buff);
				   ilen=atoi(buff);
				   	if  (ilen>=14)
				   	ilen=0;
				   memcpy(&szMID[istart],"***************",ilen);	
				  strcpy(srRcpt.szMerchantId,szMID);
		  	}
		  else
		  vdGetCPACMerchID(srRcpt.szMerchantId);
		  
		  if (srCPAC.fMaskTid)
		  	{
		  	   vdGetCPACTermID(szTID);  
			   
			          memset(buff,0x00,sizeof buff);
				   get_env_x("TIDMASKING", 0, buff);
				   istart=atoi(buff);
				   if  (istart>=8)
				   	istart=0;
				   memset(buff,0x00,sizeof buff);
				   get_env_x("TIDMASKING", 1, buff);
				   ilen=atoi(buff);
				   	if  (ilen>=8)
				   	ilen=0;

				   memcpy(&szTID[istart],"********",ilen);				   
		                strcpy(srRcpt.szTermId,szTID);
		  	}
		  else
		    vdGetCPACTermID(srRcpt.szTermId); //Bug Fix to take MID from CPAC table.

  #else
    vdGetCPACTermID(srRcpt.szTermId);
    vdGetCPACMerchID(srRcpt.szMerchantId); //Bug Fix to take MID from CPAC table.
    #endif

    //strlcpy(srRcpt.szMerchantId,srMHTRec.szMerchantID, CPAC_MERCH_ID_SIZE);
#ifdef DOWNLOAD_MULTIPLE_LOGO
    inMultipleDownloadLogo(0);
#endif /* DOWNLOAD_MULTIPLE_LOGO */

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inModifyCPACBatchRec |
*       Searches the batch record based on invoice number, changes required fields.
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inModifyCPACBatchRec(TRANSACTION_OBJECT* pobTran) {
    int inRetVal = VS_SUCCESS;   // inResult  CPAC_LINT_REMOVED
    long lnRecNum,
    lnRetVal; //,lnRecNum1; CPAC_LINT_RMD
    long lnBatchUploadSTAN;
    VS_BOOL fCloseBatch = VS_FALSE;
    VS_BOOL fCloseOTBatch = VS_FALSE;
    BATCH_KEY* psrLocalBKey;
    BATCH_REC* psrLocalBRec;
    BATCH_SKEY srBSKey;

    /** /pdebug(("--inModifyISOBatchRec--"));*/

    if (inGetLocalBatchStructures(&psrLocalBKey, &psrLocalBRec) != VS_SUCCESS) {
        ACTIVITY_LOG("Modify Batch Rec 00!");
        return VS_ERR;
    }

    /*
     *      Load Search Key Structure
     */


    // CPAC_UNBKL added from here
    srBSKey.inKeyIdx = KEY_INV_NUM + KEY_ACC_NUM;
    srBSKey.compare_func = inCompareFn;
    srBSKey.BKey.lnInvNum = str2long((char *) srISO.pszField62);
    srBSKey.BKey.lnLast4 = str2long((char *) &(srISO.pszField02[strlen((char *) srISO.pszField02) - 4]));  /* CPAC_LINT aded char * */
    // CPAC_UNBKL added till here

    if (!pobTran->fBatchOpen) {
        vdBatchDCOpen(pobTran);
        fCloseBatch = VS_TRUE;
    }

    //  lnRecNum1 = pobTran->dbBatch.kfile.curr_rec_num; //leo
    if ((lnRetVal = lnBatchGetKey(&pobTran->dbBatch, psrLocalBKey, &srBSKey, DB_FIRST, psrLocalBRec, &lnRecNum)) == 1L) {
        //      pobTran->dbBatch.kfile.curr_rec_num = lnRecNum1; //leo

        lnBatchUploadSTAN = lnGetCPACBatchUploadSTAN(&pobTran->srBRec);
        strlcpy(psrLocalBRec->szRespCode, (char *) srISO.pszField39, 2); /* CPAC_UNBKL Response Code to Batch */

        if (lnBatchUploadSTAN == 0L) {
            lnBatchUploadSTAN = srISO.lnField11;
            vdSetCPACBatchUploadSTAN(&pobTran->srBRec, lnBatchUploadSTAN);
        }
        psrLocalBKey->fUploaded = VS_TRUE;
        pobTran->srBKey.fUploaded = VS_TRUE;  //leo_may3000


        vdSetCPACRetRefNum(psrLocalBRec, srISO.pszField37);

        if (inWriteBatchData(&pobTran->dbBatch, psrLocalBKey, psrLocalBRec, lnRecNum) != VS_SUCCESS) {
            /** /pdebug (("inModifyISOBatchRec %d/%ld/%d",inResult,lnRecNum,errno));*/
            if (fCloseBatch)
                vdCloseDCBatch(pobTran);
            inRetVal = VS_ERR;
        }
        //      pobTran->dbBatch.kfile.curr_rec_num = lnRecNum1; //leo
    } else {
        if (!pobTran->fOTBatchOpen) {
            vdBatchOTOpen(pobTran);
            fCloseOTBatch = VS_TRUE;
        }

        if ((lnRetVal = lnBatchGetKey(&pobTran->dbOTBatch, psrLocalBKey, &srBSKey, DB_FIRST, psrLocalBRec, &lnRecNum)) == 1L) {
            psrLocalBKey->fUploaded = VS_TRUE;

            vdSetCPACRetRefNum(psrLocalBRec, srISO.pszField37);
            strlcpy(pobTran->srBRec.szRespCode, (char *) srISO.pszField39, 2); /* CPAC_UNBKL Response Code to Batch */

            if (inWriteBatchData(&pobTran->dbOTBatch, psrLocalBKey, psrLocalBRec, lnRecNum) != VS_SUCCESS) {
                /** /pdebug (("inModifyISOBatchRec %d/%ld/%d",inResult,lnRecNum,errno));*/
                inRetVal = VS_ERR;
            }
        }
        if (fCloseOTBatch)
            vdCloseTabBatch(pobTran);
        /** /pdebug (("inModifyISOBatchRec %ld/%d",lnRetVal,errno));*/
    }
    if (fCloseBatch)
        vdCloseDCBatch(pobTran);

    vdFreeLocalBatchStructures(psrLocalBKey, psrLocalBRec);

    return(inRetVal);
}

/*********************************************************************************************
* @func int | inCPACPIPAnalyse |
*       Function for the PACKET_OBJECT structure. Stores the response message and uploads
*       the advices
*
* @parm PACKET_OBJECT * | obPacket
*       Packet object
*
* @rdesc return values.
* @flag int | VS_SUCCESS or VS_ERR
* @end
**********************************************************************************************/

int inCPACPIPAnalyse(PACKET_OBJECT* pobPacket) {
    char szAuthCode[AUTH_CODE_SIZE + 1];
    char szStatusMessage[MESSAGE_SIZE + 1];
    unsigned char szReqMti[MTI_SIZE];   /* CPAC_UNBKL added */
    unsigned char szDummy[50];          /* CPAC_UNBKL added */
    TRANSACTION_OBJECT* pobTran;

    /** /pdebug(("--inCPACPIPAnalyse--"));*/
    pobTran = (TRANSACTION_OBJECT *) pobPacket->Transaction;

    /* get data from field table fields and put in GDS
       this needs to happen before inUploadAdvices() */
    inPFRStateStoreAll(CPAC_PFR_ANALYSE_BEGIN, pobTran, 1, 1);


    if (!fGetOffline(pobTran)) {
        // CPAC_UNBKL added {
        inLoadBitmap(((TRANSACTION_OBJECT *) pobPacket->Transaction)->srBRec.inCode, szReqMti, szDummy, szDummy);
        szReqMti[1] += 0x10;
        if (memcmp(szReqMti, Mti, MTI_SIZE) != 0) {
            ACTIVITY_LOG("MTI mismatch!");
            return(VS_ERR);
        }
        // CPAC_UNBKL added }


        strlcpy(pobTran->srBRec.szAuthCode, (char *) srISO.pszField38, FIELD38_SIZE); /* Auth Code to Batch */

        strlcpy(pobTran->srBRec.szRespCode, (char *) srISO.pszField39, FIELD39_SIZE); /* Response Code to Batch */
        /* Host date & time to pobTran */
        strlcpy(pobTran->srBRec.szTime, (char *) srISO.pszField12, DATE_SIZE);
        strlcpy(pobTran->srBRec.szDate, (char *) srISO.pszField13, DATE_SIZE);
        vdCPACSyncHostDateTime(pobTran->srBRec.szDate, pobTran->srBRec.szTime);
    }

#ifdef VXEMVAPP
	if (pobTran->srBRec.inChipStatus==EMV_CARD && !fGetOffline(pobTran)) {
		usEMVUpdateTLVInCollxn(TAG_8A_AUTH_RESP_CODE , (byte *)srISO.pszField39, 2);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_8A_AUTH_RESP_CODE = %s]", TAG_8A_AUTH_RESP_CODE, srISO.pszField39));
	}

        if ((strcmp(pobTran->srBRec.szRespCode, "00") == 0) ||
            (strcmp(pobTran->srBRec.szRespCode, "10") == 0) ||
            (strcmp(pobTran->srBRec.szRespCode, "11") == 0))
        {
            pobTran->srBRec.inTransactionResult = AUTHORIZED;
            vdSGErrorMessage(0L);
            vdSGRespMsg("Approval");
    	}
    	else if ((strcmp(pobTran->srBRec.szRespCode, "01") == 0) ||
            (strcmp(pobTran->srBRec.szRespCode, "02") == 0))
        {
			pobTran->inEMVCardDecision = EMV_VOICE_REFERRAL;
            pobTran->srBRec.inTransactionResult = REFERRAL;
            vdSGErrorMessage(0L);
            vdSGRespMsg("Referral");
    	}
    	else if (strcmp(pobTran->srBRec.szRespCode, "05") == 0)
        {
            pobTran->srBRec.inTransactionResult = DECLINED;
            vdSGErrorMessage(TRANS_FAIL_ERR_MSG21);
            vdSGRespMsg("Declined");
    	}
    	else
    	{
    	    pobTran->inOnlineFailed = EMV_COMMS_FAILURE;
            pobTran->srBKey.fOffline = VS_TRUE;
        }
	//inGlobalNumberScripts = createScriptFiles(pobPacket->pchReceiveBuff);
	inGlobalNumberScripts = 0;
#endif
    if ((!fGetOffline(pobTran)) && (pobTran->srBRec.inType != ADMIN_TRAN) && inGetNumAdv())
        // CPAC_UNBKL added inGetHDTNumAdv()
        inUploadCPACAdvices(VS_FALSE, pobTran);

    memset(szStatusMessage, 0, sizeof(szStatusMessage));

    vdGetMessageFromFile(TRANS_APP_MSG, szStatusMessage);
    strlcpy(szAuthCode, pobTran->srBRec.szAuthCode, AUTH_CODE_SIZE);


    vdSGRespMsg(szStatusMessage);

    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inUploadCPACAdvices |
* This function uploads the pending Advice records to the host.
* This should be called at the end of an ONLINE transaction.
* It also updates the batch record for a particular uploaded advice.
*
* @devnote Note that this function requires that the connection
*          to the host should be existing already.
*
* @parm VB_BOOL | fSettle |
*       Flag to identify if this is a settlement operation.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @rdesc Returns the success.
* @flag int | PIP Engine Return Value for the last uploaded host.
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inUploadCPACAdvices(VS_BOOL fSettle,TRANSACTION_OBJECT* pobTran) {
    int inRetVal = VS_SUCCESS;

    char szAcctNo[PAN_SIZE + 1];
    char szExpDate[EXP_DATE_SIZE + 1];
    char szRespCode[RESP_CODE_SIZE + 1];
    char szAuthCode[AUTH_CODE_SIZE + 1];
    char szProcCode[PROC_CODE_SIZE + 1];
    char szPOSEntryMode[POS_EM_SIZE + 1];
    char stTrack1[TRACK1_SIZE];
    char stTrack2[TRACK2_SIZE];
    char szRetRefNum[RET_REF_SIZE + 1];
    char szDate[DATE_SIZE + 1];
    char szTime[TIME_SIZE + 1];
    char szMsgId[MTI_SIZE + 1];
    long lnSTAN = 0;
    long lnOrgSTAN = 0;
    long lnInvNum = 0;
    //DB_FILE dbCPACBatch;
    //long  lnRecNum;  CPAC_LINT_RMD

    unsigned char * pchHostData;           // CPAC_ATL_MONQ
    TRANSACTION_OBJECT obTran;   // CPAC_ATL_MONQ


    //memcpy (&dbCPACBatch, &pobTran->dbBatch, sizeof (dbCPACBatch));
    //dbCPACBatch = pobTran->dbBatch;

    /* Save the present state before starting upload */
    if (!fSettle) {

        strcpy(szAcctNo, pobTran->srBRec.szPAN);
        strcpy(szExpDate, pobTran->srBRec.szExpDate);
        strcpy(szRespCode, pobTran->srBRec.szRespCode);

        strlcpy(szAuthCode, pobTran->srBRec.szAuthCode, AUTH_CODE_SIZE);

        memcpy(szProcCode, (char *) srISO.pszField03, PROC_CODE_SIZE);
        strlcpy(szPOSEntryMode, (char *) srISO.pszField22, POS_EM_SIZE);
        memcpy((char *) stTrack2, (char *) pobTran->srBRec.stT2Data, TRACK2_SIZE);
        memcpy((char *) stTrack1, (char *) pobTran->srBRec.stT1Data, TRACK1_SIZE);
        memcpy(szMsgId, Mti, MTI_SIZE);
        strlcpy(szRetRefNum, (char *) srISO.pszField37, RET_REF_SIZE);
        strcpy(szDate, pobTran->srBRec.szDate);
        strcpy(szTime, pobTran->srBRec.szTime);
        lnSTAN = pobTran->srBRec.lnSTAN;
        lnOrgSTAN = pobTran->srBKey.lnOrgSTAN;
        lnInvNum = pobTran->srBKey.lnInvNum;   //leo_may2900


        //lnRecNum = pobTran->dbBatch.kfile.curr_rec_num;

        memcpy((char *) &obTran, (char *) pobTran, sizeof(TRANSACTION_OBJECT)); // CPAC_ATL_MONQ

        if (inCPACCreateVariantStruct60() == VS_ERR) {
            vdFree((char *) psrVariant60);
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            ACTIVITY_LOG("No memory 01!");
            return(VS_ERR);
        }

#ifdef ICICI
    	if (inCPACCreateVariantStruct63 () == VS_ERR)  //LIEM : Change to CPAC to avoid confusing
    	{
            vdFreeVariantTables();
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            ACTIVITY_LOG("No memory 02!");
            return(VS_ERR);
        }

#else

	if (inCPACCreateVariantStruct63 () == VS_ERR)
    	{
            vdFreeVariantTables();
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            ACTIVITY_LOG("No memory 02!");
            return(VS_ERR);
        }

#endif   /* ICICI   */
#ifdef  UPDATE_ADV_STAN    /*   Saritha_b1 changed from TLFB to UPDATE_ADV_STAN */
        if (fGetCPACStanInc())
            inIncSTAN();      // just for teting ******* remove *******
#endif /* UPDATE_ADV_STAN     Saritha_b1 changed from TLFB_LOXBIT  to UPDATE_ADV_STAN */
    }

    if (fSettle)
        if (inCPACDoReversal(pobTran, CPAC_SEND_SIZE) != VS_SUCCESS) {
            //  BT_TRACE
            ACTIVITY_LOG("inCPACDoReversal fSettle!");
            return (VS_ERR);
        }

    if (inCPACNewUploadAdvices(fSettle, pobTran, CPAC_SEND_SIZE, VS_FALSE) != VS_SUCCESS) {
        //BT_TRACE
        inRetVal = VS_ERR;
    }

    //memcpy (&pobTran->dbBatch, &dbCPACBatch, sizeof (dbCPACBatch));
    //pobTran->dbBatch = dbCPACBatch;

    /* Restore the previous state before going back */
    if (!fSettle) {

        pobTran->srBKey.lnInvNum = obTran.srBKey.lnInvNum;      // CPAC_ATL_MONQ
        inGetDCInvBatchRec(pobTran, (int) pobTran->srBKey.lnInvNum, DB_FIRST);                  // CPAC_ATL_MONQ
        pchHostData = pobTran->srBRec.pchHostData;
        memcpy((char *) pobTran, (char *) &obTran, sizeof(TRANSACTION_OBJECT)); // CPAC_ATL_MONQ
        pobTran->srBRec.pchHostData = pchHostData; // CPAC_ATL_MONQ

#if 0
/************ Leon, pls have a look at here  ************************************/
        pobTran->srBKey.lnInvNum = lnInvNum;   //leo_may2900
        if (inGetDCInvBatchRec(pobTran, DB_FIRST) != VS_SUCCESS) return (VS_ERR);
/* It no longer overwrites, but the voided transaction is overwritten with the
 original transaction since we are reloading the record
*/
/************ Leon, pls have a look at here  ************************************/
#endif /* 0 */

        strcpy(pobTran->srBRec.szPAN, szAcctNo);
        strcpy(pobTran->srBRec.szExpDate, szExpDate);
        strcpy(pobTran->srBRec.szRespCode, szRespCode);
        strcpy(pobTran->srBRec.szAuthCode, szAuthCode);
        memcpy((char *) srISO.pszField03, szProcCode, PROC_CODE_SIZE);
        strlcpy((char *) srISO.pszField22, szPOSEntryMode, POS_EM_SIZE);
        memcpy(pobTran->srBRec.stT2Data, stTrack2, TRACK2_SIZE);
        memcpy(pobTran->srBRec.stT1Data, stTrack1, TRACK1_SIZE);
        memcpy(Mti, szMsgId, MTI_SIZE);
        strlcpy((char *) srISO.pszField37, szRetRefNum, RET_REF_SIZE);
        strcpy(pobTran->srBRec.szDate, szDate);
        strcpy(pobTran->srBRec.szTime, szTime);
        pobTran->srBRec.lnSTAN = lnSTAN;
        pobTran->srBKey.lnOrgSTAN = lnOrgSTAN;

        //  pobTran->dbBatch.kfile.curr_rec_num = lnRecNum;
    }

    return(inRetVal);
}

/*********************************************************************************************
* @func int | inCPACDoReversal |
* This function uploads the pending reversal records to the
* host. This should be called at the beginning of the settlement
* transaction but after space is allocated for variant structures.
*
* @devnote Note that this function requires that the connection to the host should
*          be existing already.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @parm int | inISOSendSize |
*       Maximum number of bytes in the request packet
*
* @rdesc Returns the success.
* @flag int | PIP Engine Return Value for the last uploaded host.
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inCPACDoReversal(TRANSACTION_OBJECT* pobTran,int inISOSendSize) {
    int inRetVal = VS_SUCCESS;
	
LOG_PRINTFF((0x08L, "--inCPACDoReversal--"));
    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("Insufficient Memory 01");
        return (VS_ERR);
    }

    vdGetReversalFileName((char *) stRevFileName, shGetHostGroupRef());
    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, inISOSendSize, VS_TRUE)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        vdFreeISO8583Data(psrHostData);
        ACTIVITY_LOG("Insufficient Memory 01");
        return (VS_ERR);
    }

	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //

#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;

    /* Added for Custom base resp validation CPAC_VALID */
   #ifdef  HDFC_INDIA/* DEFINE THE ID HDFC TO COMEOUT THE REVERSAL PROBLEM */
   ????
    		psrHostData->c8583_data->transceiver = inHDFCTxRx8583;/*venu_reversal*/
   #endif /*HDFC*/

    psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation;

    /* Added for Custom base resp validation CPAC_VALID */


    /* Disable reversal handling while doing advice upload */
    psrHostData->reverse_flag = 0;

    /* if settlement is true send the reversals before advices */
    inRetVal = prot_8583(psrHostData->c8583_data, REV_ONLY, psrHostData->c8583_data->comm_timeout);
    vdFreeCommData(psrHostData->c8583_data);
    vdFreeHostData(psrHostData);
    if (inRetVal > 0)
        inRetVal = 0;
	LOG_PRINTFF((0x08L, "--inCPACDoReversal--RetVal=[%d]", inRetVal));
    return(inRetVal);
}

/*********************************************************************************************
* @func int | inCPACInit |
*       Function for the PACKET_OBJECT structure. Initializes the variant structures
*       and calls all the required overload functions
*
* @parm PACKET_OBJECT * | obPacket
*       Packet object
*
* @rdesc return values.
* @flag int | VS_SUCCESS or VS_ERR
* @end
**********************************************************************************************/

int inCPACInit(PACKET_OBJECT* pobPacket) {
    if (inCPACCreateVariantStruct60() == VS_ERR) {
        vdFree((char *) psrVariant60);
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("Insufficient Memory 02");
        return(VS_ERR);
    }

    if (inCPACCreateVariantStruct63() == VS_ERR) {
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("Insufficient Memory 03");
        return(VS_ERR);
    }

    vdOverLoadLoadDataFuncs(srCPACLoadDataFuncs);

    inOverloadFieldID(INIT_VALIDATION_STRUCT, (PFI_TO) inInitializeCPACValidationStruct);
    inOverloadFieldID(MODIFY_BATCH_REC, inModifyCPACBatchRec);
    inOverloadFieldID(SET_TRANS_FIELDS, (PFI_TO) inSetCPACTransFields);

    inOverloadFieldID(UPDATE_REVERSAL, (PFI_TO) inUpdateCPACReversal);   // CPAC_UNBKL added
    memset(srISO.pszField37, 0, sizeof(srISO.pszField37));  // CPAC_UNBKL added
    memset(srISO.pszField38, 0, sizeof(srISO.pszField38));  // CPAC_UNBKL added


    return(VS_SUCCESS);
}
/*********************************************************************************************
* @func void | vdCPACDeleteTabAdvice |
* Deletes the offline tab transaction from the advice file
*
* @parm HOST_8583_DATA | *psrHostType |
*       Host data structure
* @end
**********************************************************************************************/
void vdCPACDeleteTabAdvice(HOST_8583_DATA* psrHostType) {
    int inRocHandle,
    inAdviceHandle,
    inStartPos;

    char szFileKey[FILENAME_SIZE + 1]; {
        strcpy(szFileKey, (char *) psrHostType->c8583_data->base_fname);
        strcat(szFileKey, ".roc");
        inRocHandle = open(szFileKey, O_RDWR | O_CREAT);

        szFileKey[strlen(szFileKey) - 4] = NULL_CH;
        strcat(szFileKey, ".adv");
        inAdviceHandle = open(szFileKey, O_RDWR | O_CREAT);

        inStartPos = 0;
        while (1) {
            delete_roc(inRocHandle, inStartPos);
            seek_ivlr(inAdviceHandle, (long) inStartPos, SEEK_CUR);
            delete_ivlr(inAdviceHandle, 1);
            do {
                inStartPos = search_roc(inRocHandle, psrHostType->key, inStartPos);
                /** /pdebug(("StartPos=%d",inStartPos));*/
            } while ((inStartPos & 0x8000) && (inStartPos != -1));
            if (inStartPos == -1) {
                inStartPos = 1;
                break;
            }
        }
        close(inAdviceHandle);
        close(inRocHandle);
    }
}

/*********************************************************************************************
* @func void | vdCPACError |
* Handles errors returned from pip_trans().
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @parm int | inError |
*       Error returned from pip_trans()
*
* @end
**********************************************************************************************/

void vdCPACError(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket,int inError) {
//#ifndef CITI_PHIL
    //jrd one source
    #ifdef __arm
    short inTransCode;
    #endif
    #ifdef _TARG_68000
     int inTransCode;
    #endif
//#endif /* CITI_PHIL */
 char szAuthCode[AUTH_CODE_SIZE + 1];
#ifdef ICICI
   char szSourceReversalFileName[20];
   char szDestReversalFielName[20];
 #endif /* ICICI  */

    char szFailMsg[MESSAGE_SIZE + 1];
    int  inCallReferralAllow=0;
    TRANSACTION_OBJECT* pobTran;
    
    pobTran = (TRANSACTION_OBJECT *) pobPacket->Transaction;

	LOG_PRINTFF((0x8L,"vdCPACError [%d]", inError));
	if (inError == -54 || inError == -53 || inError == -52) {
		/* Edi - comment 
		if (fGetImamNeedLogon()) {
			vdSetImamLogonStatus(0);
			inSaveHostData(inGetHostHandle());
			inImamLogonNow = 1;
			LOG_PRINTFF((0x08L, "LOGON HOST[%d] RESET AS [%d]", inGetHostHandle(), inError));
		}*/
	}

    switch (inError) {
    case AMEX_VOICE_AUTH:
        if (obCommunication.inEnd)
            obCommunication.inEnd(&obCommunication);

		#ifdef ICICI
			vdGetMessageFromThisFile(CPAC_RESPONSE_FILE, atoi( (char *)srISO.pszField39 ), srRcpt.szErrorMessage );
		#endif  /* ICICI  */
//#ifndef CITI_PHIL
		if (((pobTran->srTRTRec.TransactionCode == SALE) || 
			 (pobTran->srTRTRec.TransactionCode == AUTH_ONLY) || 
			 (pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) || 
			 (pobTran->srTRTRec.TransactionCode == PRE_AUTH)) &&
			(fGetImamReferral()) && 
			(pobTran->srBRec.inChipStatus != EMV_CARD) &&
			(inGetManualApproval(szAuthCode, AUTH_CODE_SIZE) == VS_TRUE )
			) {
            pad(szAuthCode, szAuthCode, SPACE, AUTH_CODE_SIZE, LEFT);
            strcpy(pobTran->srBRec.szAuthCode, szAuthCode);
            inTransCode = pobTran->srBRec.inCode;       /* save original trans code */
            vdCPACResetTrans(pobTran);                 /* changes trans code to offline */
            pobTran->fReferral = VS_TRUE;
            if (inTransCode == AUTH_ONLY || inTransCode == PRE_AUTH || inTransCode == IMAM_CARDVER) {
                //vdSetCPACOpenTabOffline(&pobTran->srBRec, VS_TRUE);
                inError = VS_SUCCESS;
            } else {
                pobTran->srBKey.lnOrgSTAN = pobTran->srBRec.lnSTAN;
                inIncSTAN(); /* increment the STAN for new transaction to host */
                pobTran->srBRec.lnSTAN = lnGetSTAN();
                //if (inTransCode == PRE_COMP) vdSetCPACOpenTabOffline(&pobTran->srBRec, VS_TRUE);
                inError = inImamReferralSendReceive(pobProtocol, pobPacket);
            }
            pobTran->srBRec.inCode = inTransCode;       /* reset original trans code */ //LIEM: NO NEED
        } else {
//#endif /* NOT CITI_PHIL */
            vdSetOffline(pobTran, VS_TRUE);
#ifndef CITI_PHIL
            vdSGErrorMessage(TXN_CANCELLED);
            vdGetMessageFromFile(TXN_CANCELLED, srRcpt.szErrorMessage);
#endif /* CITI_PHIL */

#ifndef ICICI
	#ifdef CITI_PHIL
                vdSGErrorMessage(CALL_VOICE_CENTER_MSG);
                vdGetMessageFromFile( CALL_VOICE_CENTER_MSG, srRcpt.szErrorMessage);
	#endif /* CITI_PHIL */
#endif  /*  ICICI   */

            vdSGRespMsg(srRcpt.szErrorMessage);
            inIncInvNum(); /* increment the invoice for failed transactions */
        }
        break;

    case TR_BAD_PARM:
    case AMEXHOST_ADJUST_ERROR:
    case AMEXHOST_VOID_ERROR:
    case AMEXHOST_INVADV_ERROR:
    case AMEXHOST_INV_OPTION:
    case PIP_NOT_ONLINE:
        vdSGErrorMessage(TXN_CANCELLED);
        vdGetMessageFromFile(TXN_CANCELLED, srRcpt.szErrorMessage);
        vdSGRespMsg(srRcpt.szErrorMessage);

	#ifdef ICICI
		  vdGetMessageFromThisFile(CPAC_RESPONSE_FILE, atoi( (char *)srISO.pszField39 ), srRcpt.szErrorMessage );
	#else
		 vdGetMessageFromFile(CALL_VOICE_CENTER_MSG, szFailMsg);
	#endif /* ICICI */
        vdSGRespMsg(szFailMsg);
        inIncInvNum(); /* increment the invoice for failed transactions */
        break;

    case HOST_ERROR:
#ifdef IMAM_PERMATA
			if (strlen((char *)srISO.pszField63)>0) { // for Permata style response display
				char buff[42];
				char buff1[42];
				char buff2[42];
				// : Permata : Displaying field 63 here 
				//vdDisplayMessage((char *)srISO.pszField39, WARNING_MSG);
				memset(buff, 0x00, sizeof(buff));
				memset(buff1, 0x00, sizeof(buff1));
				memset(buff2, 0x00, sizeof(buff2));
				if (strlen((char *)srISO.pszField63)>40) {
					strncpy(buff, (char *)srISO.pszField63, 40);
				} else {
					strcpy(buff, (char *)srISO.pszField63);
				}
				if (strlen(buff) > 20) {
					strncpy(buff1, buff, 20);
					strcpy(buff2, &buff[20]);
				} else {
					strcpy(buff1, buff);
				}
				vdTrimSpace(buff1);
				vdTrimSpace(buff2);
				LOG_PRINTFF((0x08L, "BIT63 = [%s]", buff));
				LOG_PRINTFF((0x08L, "Line1 = [%s]", buff1));
				LOG_PRINTFF((0x08L, "Line2 = [%s]", buff2));
				vdFormatText(buff1, 21, 0); //centered
				DisplayStatus(buff1);
				strcpy(srRcpt.szErrorMessage, buff1);
				vdSGRespMsg(srRcpt.szErrorMessage);
				if (strlen(buff2)){
					gotoxy(1,inImamLineNumber-1);
					delline();
					gotoxy(1,inImamLineNumber);
					vdFormatText(buff2, 21, 0);//Centered
					DisplayStatus(buff2);
					strcpy(srRcpt.szErrorMessage, buff1);
					vdSGRespMsg(srRcpt.szErrorMessage);
				}
				inWaitKey(2);
				inIncInvNum(); // increment the invoice for failed transactions 
			} else 
#endif
		{
        /* Must set error message here so that RespMsg will not be overlayed at end of
           BuildAndSendPacket   */
        /*  vdSGErrorMessage(TXMT_FAIL_ERR_MSG); */ // Comm error display
        #ifdef ICICI
			inTransCode = inGGCode();
			if(inTransCode == HDFC_COMM_TEST)
				{
				vdSGRespMsg("COMM TEST SUCCESSFULL");
				 inIncInvNum();
				}
			else
				{
	        vdCPACDispRespMsg(pobTran);
        inIncInvNum(); /* increment the invoice for failed transactions */
				}
	#else
			vdCPACDispRespMsg(pobTran);
        	inIncInvNum(); /* increment the invoice for failed transactions */
	#endif /* ICICI  */
		}
		{// for CUP
			if (!strncmp((char *)srISO.pszField39, "A0", 2)) {
				if (fGetImamNeedLogon()) {
					vdSetImamLogonStatus(0);
					inSaveHostData(inGetHostHandle());
					inImamLogonNow = 1;
					LOG_PRINTFF((0x08L, "LOGON HOST[%d] RESET AS AO [%d]", inGetHostHandle(), inError));
				}
			}
		}
        break;
          case AXAP_COMM_ERROR:
			                            vdSGRespMsg("COMM TEST SUCCESSFULL");
				                     inIncInvNum();
				 break;

    default:
        if (lnGGErrorMessage() == VS_FALSE) {
               /*Venu mti reversal fix*/
		  if(errno == PROT8583_RCV_MSG_ID_ERROR) //For MTI Mismatch
   		  {
   			vdSGErrorMessage(MTI_MISMATCH_MSG);
   			vdGetMessageFromFile( MTI_MISMATCH_MSG, srRcpt.szErrorMessage);
			#ifdef ICICI
			 	memset(szSourceReversalFileName,0x00,sizeof(szSourceReversalFileName));
    				vdGetReversalFileName(szSourceReversalFileName, inGetHostIndex());
    				sprintf(szDestReversalFielName, "%s%s", szSourceReversalFileName,REVERSAL_FILE_EXTN);
    				strcat(szSourceReversalFileName,BACKUP_REV_FILE_EXTN );
     				file_copy(szSourceReversalFileName, szDestReversalFielName);
			#endif /* ICICI  */
     		  }
   		else
		  {
		  	#ifdef ICICI
		  	  	//To make Comm Err more descriptive.....Renu
		  	  	//vdSGErrorMessage(TXMT_FAIL_ERR_MSG);
	                	vdGetMessageFromFile( TXMT_FAIL_ERR_MSG, srRcpt.szErrorMessage);
			  	sprintf(szFailMsg, "%s %d", srRcpt.szErrorMessage, inError);
			  	vdSGRespMsg(szFailMsg);
			  	ACTIVITY_LOG(szFailMsg);
			#else
				vdSGErrorMessage(TXMT_FAIL_ERR_MSG);
                		vdGetMessageFromFile(TXMT_FAIL_ERR_MSG, srRcpt.szErrorMessage);
			#endif  /* ICICI  */

                }
                //vdSGRespMsg(srRcpt.szErrorMessage);
            }
            inIncInvNum();
            break;
    }

    pobPacket->inError = inError;
} /* End of vdPIPError () */


/*********************************************************************************************
* @func void | vdCPACResetTrans |
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/
void vdCPACResetTrans(TRANSACTION_OBJECT* pobTran) {
    char szDate[DATE_SIZE + 1];
    char szTime[TIME_SIZE + 1];

    switch (inGGCode()) {
	case PRE_AUTH:
	case IMAM_CARDVER:
	case AUTH_ONLY:     //LIEM for AUTH_ONLY & PRE_AUTH REFERALL
    case REFUND:
        //vdSGCode(REFUND_OFFLINE);
        pobTran->srBKey.fOffline = VS_TRUE;//CPAC2.1B
        break;
    default:
        vdSGCode(SALE_OFFLINE);
        break;
    }
    vdSetOffline(pobTran, VS_TRUE);
    pobTran->srBKey.fOffline = VS_TRUE;
    vdGetDate(szDate, MMDDYY);
    strcpy(pobTran->srBRec.szDate, szDate);
    vdGetTime(szTime);
    strlcpy(pobTran->srBRec.szTime, szTime, DATE_SIZE);
}

void vdImamGetMessageFromThisFile(const  char* szFileNameSuffix, char *szMessageCode, char* szMessageBuffer) 
{
    int inMessageIndex = 99;
	inGetDefaultLCT();
	
    if (inSelectMessageFile(szFileNameSuffix) != VS_SUCCESS)
        return;

	do{
		inMessageIndex++;
//		if (msg_get(abs(inMessageIndex), szMessageBuffer) == (int)NULL) { // imam 
		if (msg_get(abs(inMessageIndex), szMessageBuffer) == NULL) {
			sprintf(szMessageBuffer, "%s-ERROR", szMessageCode);
			return;
		}
		if (!strncmp(szMessageCode, szMessageBuffer, 2)){
			return;
		}
	} while (inMessageIndex<200);
}

/*********************************************************************************************
* @func void | vdCPACDispRespMsg |
* Fills the Display Buffer with the relevant display string.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @end
**********************************************************************************************/

void vdCPACDispRespMsg(TRANSACTION_OBJECT* pobTran) {
    char szMessage[MESSAGE_SIZE + 1];

    if (!strncmp((char *) srISO.pszField39, "00", 2)) {
        vdSGErrorMessage(TXMT_FAIL_ERR_MSG);
        vdGetMessageFromFile(TXMT_FAIL_ERR_MSG, srRcpt.szErrorMessage);
        vdSGRespMsg(srRcpt.szErrorMessage);
    } else {
        vdGetMessageFromFile(AMEX_ERROR_MSG15, szMessage);
        strncat(szMessage, (char *) srISO.pszField39, FIELD39_SIZE);
        vdSGRespMsg(szMessage);
        //CPAC_UNBKL_FUTURE added
		if (atoi((char *) srISO.pszField39)>0 && atoi((char *) srISO.pszField39)<100) {
			vdGetMessageFromThisFile(CPAC_RESPONSE_FILE, atoi((char *) srISO.pszField39), srRcpt.szErrorMessage);
		} else {
			vdImamGetMessageFromThisFile(CPAC_RESPONSE_FILE, (char *)srISO.pszField39, srRcpt.szErrorMessage);			
		}
        vdSGRespMsg(srRcpt.szErrorMessage);
		LOG_PRINTFF((0x08L, "RESPONSE CODE [%s] = [%s]", (char *)srISO.pszField39, (char *)srRcpt.szErrorMessage));
        //CPAC_UNBKL_FUTURE added
    }
}

/*********************************************************************************************
* @func int | inSetCPACOffOnLine |
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       This is the transaction object.
*
* @rdesc Returns the success.
* @flag int | PIP Engine Return Value for the last uploaded host.
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inSetCPACOffOnLine(TRANSACTION_OBJECT* pobTran) {
    if (pobTran->srBKey.fVoided) {
        if (pobTran->srBKey.fUploaded)
            pobTran->srTRTRec.Offline = VS_FALSE;
        else
            pobTran->srTRTRec.Offline = VS_TRUE;
    }
#ifndef CITI_IND
    if ((pobTran->srBRec.inCode == SALE_OFFLINE) && (pobTran->srBKey.fVoided == VS_TRUE)) //Fix so that
        #endif /*Not CITI_IND*/                                                                 //CITI_IND requires VOID to go offline
        pobTran->srTRTRec.Offline = VS_TRUE;                                            //void of an offline sale
    //is always offline...
    if (pobTran->srTRTRec.TransactionCode == ADJUST || pobTran->srTRTRec.TransactionCode == CPAC_PHIL_ADJUST ||  /* 1.4_citiphil_26feb_don_DSC */
        pobTran->srTRTRec.TransactionCode == TIP_ADJUST || pobTran->srTRTRec.TransactionCode == ADD_TIP_OFFLINE)
        pobTran->srTRTRec.Offline = VS_TRUE;


    return(VS_SUCCESS);
}

void vdCPACSyncHostDateTime(char* hostdate,char* hosttime) 
{
	char TermDateTime[FORMATTED_DATE_SIZE + TIME_SIZE + 1];
    SVC_CLOCK(GET_CLOCK, TermDateTime, 15);
    memcpy(&TermDateTime[4], hostdate, 4);
    memcpy(&TermDateTime[8], hosttime, 6);
    SVC_CLOCK(SET_CLOCK, TermDateTime, 14);
	LOG_PRINTFF((0x08L, "IMAM ==> CLOCK SYNCH DONE"));
}

#ifdef CITI_PHIL
void vdMaskCitiMTID(void) {
    char szTime1[TIME_SIZE + 1];
    vdGetTime(szTime1);

    memcpy(srRcpt.szTermId, &szTime1[3], 3);
    memcpy(srRcpt.szMerchantId, &szTime1[3], 3);
    srRcpt.szMerchantId[14] = NULL_CH;
}
#endif /* CITI_PHIL */





/*********************************************************************************************
* @func int | inUpdateCPACReversal |
*       Empty function for prot8583_main in appl.c
*
* @parm COMM_8583_DATA * | srCommStruct
*       ISO communication data structure
*
* @rdesc return values.
* @flag int | VS_SUCCESS
* @end
**********************************************************************************************/
extern char* strchr(const char*,int);

static void vdFindField(int fld,field_struct* table,field_struct** dptr) {
    while (table->field_num != fld)
        table++;
    *dptr = table;
}

int inUpdateCPACReversal(COMM_8583_DATA* srCommStruct) {
    field_struct* fld_35,
    * fld_2,
    * fld_14;
    char* ptr;
    char temp[56];


    vdFindField(35, srCommStruct->p_fld_table, &fld_35);
    vdFindField(2, srCommStruct->p_fld_table, &fld_2);
    vdFindField(14, srCommStruct->p_fld_table, &fld_14);

    //  if( ((unsigned char*)fld_35->reference)[0] )
    if (map_test(srCommStruct->map, 35)) {
        strcpy(temp, (const char *) (fld_35->reference));
        ptr = strchr(temp, '=');
        strncpy(fld_2->reference, temp, ptr - temp);
        strncpy(fld_14->reference, ptr + 1, 4);

        map_set(srCommStruct->map, 2);
        map_set(srCommStruct->map, 14);
        map_reset(srCommStruct->map, 35);
    }

    /* Added for Custom base resp validation CPAC_VALID */

    srCommStruct->validation = (PFI_PVOID_INT) inCPACBaseRespValidation;

    /* Added for Custom base resp validation CPAC_VALID */

    return(VS_SUCCESS);
}

#ifdef IMAM_AMEX_REVERSAL
int inUpdateAMEXReversal(COMM_8583_DATA* srCommStruct)
{

	field_struct *fld_35, *fld_2, *fld_14,*fld_55, *fld_45;
	char *ptr, *ptr1;
	char temp[TRACK1_SIZE+1], temp1[TRACK1_SIZE+1];//Changed the buffer size from 56 to Track1 size as that is the max size reqd.
	char szPAN[PAN_SIZE+1];

	memset(szPAN, 0x00, sizeof(szPAN));
	memset(temp, 0x00, sizeof(temp));
	memset(temp1, 0x00, sizeof(temp1));

	vdFindFieldAMEX( 35, srCommStruct->p_fld_table, &fld_35 );
	vdFindFieldAMEX( 2, srCommStruct->p_fld_table, &fld_2 );
	vdFindFieldAMEX( 14, srCommStruct->p_fld_table, &fld_14 );
       vdFindFieldAMEX( 55, srCommStruct->p_fld_table, &fld_55 );
	vdFindFieldAMEX( 45, srCommStruct->p_fld_table, &fld_45 );

//	if( ((unsigned char*)fld_35->reference)[0] )
	if( map_test( srCommStruct->map, 35 ) )
	{

		strcpy( temp, (const char*)(fld_35->reference) );
		ptr = strchr( temp, '=' );
		strncpy( fld_2->reference, temp, ptr-temp );
		strncpy( fld_14->reference, ptr+1, 4 );

		map_set( srCommStruct->map, 2 );
		map_set( srCommStruct->map, 14 );
		map_reset( srCommStruct->map, 35 );
		map_reset( srCommStruct->map, 45 ); //Praveen 09022005 - Fix for Track1 reversal issue
	}

	/*START:  Praveen 07022005  - To enable/disable 4DBC and Track 1 based on the card label */
	else if (fValidateAmexCardSpecific(REQ_TRACK1) == VS_TRUE)
	{
		/* To turn off field 45 (TrackOne data) in the reversal*/
		/* Modified to send 2 and 14 when Track One is present*/
		if( map_test( srCommStruct->map, 45 ))
		{
			strcpy(temp, (const char*)(fld_45->reference));
			ptr = strchr(temp, '^');
			strncpy(szPAN, &temp[1], ptr-temp-1);
			vdRemoveSpaces(fld_2->reference, szPAN);

			strcpy(temp1, &temp[ptr-temp+1]);
			ptr1 = strchr(temp1, '^');
			strncpy(fld_14->reference, &ptr1[1],4 );

			map_set( srCommStruct->map, 2 );
			map_set( srCommStruct->map, 14 );
			map_reset(srCommStruct->map, 45 );
		}
	}
	/*END:  Praveen 07022005  - To enable/disable 4DBC and Track 1 based on the card label */

//jrd
	if( map_test( srCommStruct->map, 55 ))	//MOdifed by KiaSoon 25012006
		map_reset(srCommStruct->map, 55 );

/* Below block of code moved up so that Fld 2 and 14 are read from Fld 45 only if Fld 35 is not present.*/
/* To turn off field 45 (TrackOne data) in the reversal*/
/* Modified to send 2 and 14 when Track One is present*/
/*if( map_test( srCommStruct->map, 45 ))
{
	strcpy(temp, (const char*)(fld_45->reference));
	ptr = strchr(temp, '^');
	strncpy(szPAN, &temp[1], ptr-temp-1);
	vdRemoveSpaces(fld_2->reference, szPAN);

	strcpy(temp1, &temp[ptr-temp+1]);
	ptr1 = strchr(temp1, '^');
	strncpy(fld_14->reference, &ptr1[1],4 );

	map_set( srCommStruct->map, 2 );
	map_set( srCommStruct->map, 14 );
	map_reset(srCommStruct->map, 45 );
}*/

   /* Added for Custom base resp validation CPAC_VALID */

    //srCommStruct->validation  = inCPACBaseRespValidation;
    srCommStruct->validation = (PFI_PVOID_INT) inAXAPBaseRespValidation; //Praveen_s1 07032005 - Ported from 9.4.6

   /* Added for Custom base resp validation CPAC_VALID */

	return(VS_SUCCESS);

}
//END: Praveen 06122004 - Track 1 Fix
#endif  //for reference

int inLoadCPACRecForPowerFail(TRANSACTION_OBJECT* pobTran) {
    vdLoadCPACParams(&srCPAC);
    return(VS_SUCCESS);
}



/*********************************************************************************************
* @func int | inCPACBaseRespValidation |
* This routine checks the response against the following
* fields that are stored in the validation structure and is
* called by the PIP Engine.  The pointer to this function
* is passed to the PIP Engine in the PIP Engine Communications
* Data Structure (COMM_8583_DATA).
*
* @parm VALIDATION_STRUCT * | psrRespValStruct |
*       Validation structure.
*
* @parm int | inInternalVal |
*       Not used
*
* @rdesc Returns the success.
* @flag int | PIP Engine Return Value for the last uploaded host.
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inCPACBaseRespValidation(VALIDATION_STRUCT* psrRespValStruct,int  inInternalVal) {
    VALIDATION_STRUCT* psrValStruct;
    VALIDATION_STRUCT srLocalValStruct;
    VALIDATION_STRUCT* psrValidStruct;
    int inRetVal = 0;
    field_struct* psrFieldArray;
	
	LOG_PRINTFF((0x08L, "--inCPACBaseRespValidation--"));
    /** /pdebug(("--inCPACBaseRespValidation--"));*/

    /*    Check for please wait message "0820" and Amex hangup
       string. */

    /* PIP engine calls this function with a void pointer instead of a sturcture pointer */

    psrValidStruct = (VALIDATION_STRUCT *) psrRespValStruct;
    if ((inRetVal = inBaseValidationLow(psrValidStruct, 0)) != 0) {
        return (inRetVal);
	}
	LOG_PRINTFF((0x08L, "after calling inBaseValidationLow..OK"));
    /*     If processing the reversal, the amount, trace #, and
        tid are located in the first 29 bytes of the store
        buffer.  Read this data into the local validation struct
        for validation.
    */

    if (psrValidStruct->comm_struct->state > TRAN_REQ) {
        /** /pdebug (("state > TRAN_REQ"));*/
        memcpy(&srLocalValStruct, psrValidStruct->comm_struct->reversal, psrValidStruct->comm_struct->v_parms_size);

        srLocalValStruct.p_amount = psrValidStruct->p_amount;
        srLocalValStruct.p_tid = psrValidStruct->p_tid;
        srLocalValStruct.p_trace = psrValidStruct->p_trace;
        psrValStruct = &srLocalValStruct;
    } else {
        memcpy(&srLocalValStruct, psrValidStruct->comm_struct->transmit, psrValidStruct->comm_struct->v_parms_size);
        srLocalValStruct.p_amount = psrValidStruct->p_amount;
        srLocalValStruct.p_tid = psrValidStruct->p_tid;
        srLocalValStruct.p_trace = psrValidStruct->p_trace;
        psrValStruct = &srLocalValStruct;
    }

    vdTrimLeadZeroes((char *) psrValStruct->b_amount);
    vdTrimLeadZeroes((char *) psrValidStruct->p_amount);
    pad((char *) psrValStruct->b_tid, (char *) psrValStruct->b_tid, ' ', TID_SIZE, LEFT);
    pad((char *) psrValStruct->p_tid, (char *) psrValStruct->p_tid, ' ', TID_SIZE, LEFT);

    if (map_test(stMap8583, 41)) {
        if (strcmp((char *) psrValStruct->b_tid, (char *) psrValidStruct->p_tid)) {
            /** /pdebug(("Terminal Id Error"));*/

            ACTIVITY_LOG("Terminal Id:CPAC Base Resp");
		        vdDisplayMessage("TID MISMATCH", STATUS_MSG);
            inRetVal = RETRY_CONTROL_TIMEOUT;
        }
    }

    if (map_test(stMap8583, 11)) {
        /** /pdebug (("trace = %ld", psrValStruct->b_trace));*/
        /** /pdebug (("trace = %ld", *(psrValStruct->p_trace)));*/
        if (psrValStruct->b_trace != *(psrValidStruct->p_trace)) {
            /** /pdebug (("STAN ERROR"));*/
            ACTIVITY_LOG("Stan:CPAC Base Resp");
            vdDisplayMessage("STAN MISMATCH", STATUS_MSG);
            inRetVal = RETRY_CONTROL_TIMEOUT;
        }
    }

#if MAL_WANTS   // Malaysia does not need this
    if (strcmp((char *) psrValStruct->b_amount, (char *) psrValidStruct->p_amount)) {
        /** /pdebug(("Amount Error %s %s", psrValStruct->b_amount, (char *)psrValidStruct->p_amount));*/
        ACTIVITY_LOG("Amount:CPAC Base Resp");
        inRetVal = RETRY_CONTROL_TIMEOUT;
    }
#endif /* MAL_WANTS */

#ifdef MTI_VALIDATION_REQ
    psrAddValStruct->stMti[1] += 0x10;
    if (memcmp(psrAddValStruct->stMti, psrAddValStruct->pchMti, 2)) {
        ACTIVITY_LOG("MTI Mismatch:CPAC Base Resp");
        inRetVal = RETRY_CONTROL_TIMEOUT;
    }
#endif /*MTI_VALIDATION_REQ*/

#ifdef PROC_VALIDATION_REQ
    if (memcmp(psrAddValStruct->stProcCode, psrAddValStruct->pchProcCode, 3)) {
        ACTIVITY_LOG("Proc Code Mismatch:CPAC Base Resp");
        inRetVal = RETRY_CONTROL_TIMEOUT;
    }
#endif /*PROC_VALIDATION_REQ*/

#ifdef NII_VALIDATION_REQ
    if (strcmp(psrAddValStruct->szNII, psrAddValStruct->pchNII)) {
        ACTIVITY_LOG("NII Mismatch:CPAC Base Resp");
        inRetVal = RETRY_CONTROL_TIMEOUT;
    }
#endif /*NII_VALIDATION_REQ*/
    /* if reversal response - check for dcp and return an error
     * code to tell protocol level to stop processing.  This error
     * code is returned to the host level and is used to generate
     * a Reversal Advice (0420).
     */

    //vdDisplayAt(1, 2, "CPAC Validation", CLR_EOL);  /* CPAC_TBD_REM */

    if (inRetVal != RETRY_CONTROL_TIMEOUT) {
        if ((inRetVal = check_8583_tpdu_msg_id(psrValidStruct->comm_struct, psrValidStruct->comm_struct->p_fld_table[1].reference, (unsigned char *) "\004\000")) > -50) {
            /***
            Look at the response code to the reversal request and determine
            if it is approved (=="00"). If it is not, then return with error.
            This way, the reversal will not be deleted.
            ***/
            psrFieldArray = (field_struct *) find_field_index(39, psrValidStruct->comm_struct->p_fld_table);

            if (strcmp(psrFieldArray->reference, "00")) {
                ACTIVITY_LOG("Reversal not approved BaseRespVal");
                return(-1);
            }

            psrFieldArray = (field_struct *) find_field_index(44, psrValidStruct->comm_struct->p_fld_table);

            /* inRetVal will equal -75 when dcp approves a pending
             * reversal and -76 when dcp approves a new reversal
             */
            if (!(strcmp(psrFieldArray->reference, "02")) && map_test(psrValidStruct->comm_struct->map, 44))
                inRetVal = AMEX_DCP_REVERSAL - psrValidStruct->comm_struct->state;
            else
                inRetVal = 0;
        } else
            inRetVal = 0;

        /* Added fix duplicate advice  issue **/
        if ((inRetVal = check_8583_tpdu_msg_id(psrValidStruct->comm_struct, psrValidStruct->comm_struct->p_fld_table[1].reference, (unsigned char *) "\002\020")) > -50) {
            /***
            Look at the response code to the advice request and determine
            if it is a duplicate (=="94"). If it is set the response code to "00"
            so the advice record will be deleted.
            ***/
            psrFieldArray = (field_struct *) find_field_index(39, psrValidStruct->comm_struct->p_fld_table);

            if (!strcmp(psrFieldArray->reference, "94"))
                strncpy(psrFieldArray->reference, "00", 2);

            inRetVal = 0;
        } else
            inRetVal = 0;

        /** Added fix duplicate advice issue **/
    }

	LOG_PRINTFF((0x08L, "--inCPACBaseRespValidation--RetVal=[%d]", inRetVal));
    return(inRetVal);
}

/******************************************************************************
* @func int | inCITIUserChoice |
*
*       This function prompts user to choose which search path
*       they want for VOID - Invoice number or last 4 digits of
*       account number.  This is to take into account Open Tab
*       processing.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
*
* @flag int    |    VS_SUCCESS
*                   VS_ESCAPE
* @end
*******************************************************************************/

int inCITIUserChoice(TRANSACTION_OBJECT* pobTran) {
    short inTranCode,
    inOperationCode,
    inRetVal;
    long lnDBWhat = DB_FIRST;


    /** /pdebug (("--inUserChoice--"));*/

    inTranCode = pobTran->srTRTRec.TransactionCode;
    inOperationCode = inGGOpCode();
    if (inOperationCode == BATCH_REVIEW_OPERATION)
        return (VS_SUCCESS);


    do {
        inRetVal = inGetInvoiceNumber(pobTran);
        if (inRetVal != VS_SUCCESS) {
            inRetVal = VS_ERR;
            break;
        }

        if ((inRetVal = inGetDCInvBatchRec(pobTran, pobTran->srBSKey.inKeyIdx, lnDBWhat)) != VS_SUCCESS)
            vdDisplayErrorMessage(CPAC_NO_MATCH_MSG);
    } while (inRetVal != VS_SUCCESS);

    return (inRetVal);
}


int inRemoveLastRecieptFile(TRANSACTION_OBJECT* pobTran) 
{
    DB_FILE dbReprintFile;

	{//LIEM Add to correct batch vs accum issue of multiple charge
		int inRetval = inImamBatchCorrection(pobTran);
	}

    if (db_open(&dbReprintFile, REPRINT_FILE_NAME, SIZE_BATCH_KEY, (O_TRUNC | O_CREAT | O_RDWR)) < 0) {
        ACTIVITY_LOG("Open FAIL");
        return(VS_ERR);
    }

    db_delete(&dbReprintFile, 0L, 1L) ;

    if (inCloseBatch(&dbReprintFile) != VS_SUCCESS)
    {

        vdSGErrorMessage(BATCH_ERR_MSG);
	}
    return(VS_SUCCESS);

    /* fd=open(REPRINT_FILE_NAME, O_TRUNC);
    if ( fd <=0) {
        ACTIVITY_LOG("CLEAR FAIL");
        return(VS_ERR);
    }
    else {
        close(fd);
        ACTIVITY_LOG("CLEAR SUCCESS");
        return(VS_SUCCESS);
    } */
}



int inCPACLoadMissingTable(TRANSACTION_OBJECT* pobTran) {
    //inLoadMHTRec(pobTran->srBKey.inBatchHostIndex);can be removed as core pfr takes care 1.4
    //inLoadCSTRec ( pobTran->srBKey.inCurrencyIndex );
    //inLoadCDTandCST (pobTran); can be removed as core pfr takes care 1.4
    inLoadDefaultCurrency(pobTran);
    inLoadCSTRec(pobTran->srBKey.inCurrencyIndex);
    inGetIssuerRecord(inGetIssuerNum()); // CPAC21.B
    vdLoadCPACParams(&srCPAC);
    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inCPACNewUploadAdvices|
* This function uploads the pending Advice records to the host.
* This should be called at the end of an ONLINE transaction.
* It also updates the batch record for a particular uploaded advice.
*
* @devnote Note that this function requires that the connection
*          to the host should be existing already.
*  Moved this function from the core to the custom, to modify the code
*  for duplicate advice fix.
*
* @rdesc Returns the success.
* @flag int | PIP Engine Return Value for the last uploaded host.
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inCPACNewUploadAdvices(VS_BOOL fSettle,TRANSACTION_OBJECT* pobTran,int inISOSendSize,VS_BOOL fReversalFlag) {
    int inRetVal;
    int inTransType;
    int inMaxAdvices = 0;
    //long lnSTAN;        CPAC_LINT
    char szMessage[RESP_MSG_SIZE + 1];


    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdGetMessageFromThisFile(PIP_MESSAGE_FILE, NO_MEMORY_ERR_MSG, szMessage);
        vdDisplayErrorString(szMessage);
        return (VS_ERR);
    }

    vdGetReversalFileName((char *) stRevFileName, shGetHostGroupRef());
    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, inISOSendSize, fReversalFlag)) == (COMM_8583_DATA *) NULL_CH) {
        vdFreeCommData(psrHostData->c8583_data);
        vdFreeHostData(psrHostData);
        vdGetMessageFromThisFile(PIP_MESSAGE_FILE, NO_MEMORY_ERR_MSG, szMessage);
        vdDisplayErrorString(szMessage);
        return (VS_ERR);
    }

	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;

    /* Added fix for duplicate advice check */

    psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation; //dup_adv


    /* Disable reversal handling while doing advice upload */
    psrHostData->reverse_flag = 0;

    /* Get the maximum number of piggy-back transactions for this host */
    if (fSettle == VS_FALSE)
        inMaxAdvices = inGetNumAdv();

#ifdef AMEX_PROC_CODE_CHNG
    if (strcmp(szGetHostFileName(), "AXAP") == 0)
        inMaxAdvices = min(inGetNumAdv(), inAdvCnt);
#endif /* AMEX_PROC_CODE_CHNG  */

    /* Set the PIP transaction type to "Send Advice" mode */
    inTransType = A_SEND_ADVICE;
    /* Start Uploading the offline records to the host */
    do {
#ifdef UPDATE_ADV_STAN    /*   Saritha_b1 changed from TLFB to UPDATE_ADV_STAN */
        if (fGetCPACStanInc())
            inCPACModifyAdvice(psrHostData);
#endif   /*UPDATE_ADV_STAN       Saritha_b1 changed from TLFB to UPDATE_ADV_STAN */

        /*   Saritha_b1............Amex Proc Code last bit changing.......*/
#ifdef AMEX_PROC_CODE_CHNG
        if (fSettle == VS_FALSE) {
            if (strcmp(szGetHostFileName(), "AXAP") == 0) {
                if ((inMaxAdvices == 1) && (!fSettle))
                    inAXAPModifyAdvProcCode0(psrHostData);
                else
                    inAXAPModifyAdvProcCode1(psrHostData);
            }
        }
#endif /* AMEX_PROC_CODE_CHNG */


        /*   Saritha_b1............Amex Proc Code last bit changing.......*/
        strcpy((char *) srISO.pszField44, "00");
        inRetVal = pip_trans(inTransType, psrHostData);
        if (inRetVal == AMEX_NO_ADVICE) {
            inRetVal = VS_SUCCESS;
            break;
        }
        /* Abort settlement if DCP approval on advice */

        if (!(strncmp((char *) srISO.pszField44, "02", 2)) && (fSettle)) {
            //vdSGErrorMessage(ADVICE_UPLOAD_ERR_MSG);
            ACTIVITY_LOG("Advice upload 01"); // Duplicate advice fix
            vdGetMessageFromThisFile(PIP_MESSAGE_FILE, DCP_APPROVAL_MSG, szMessage);
            vdSGRespMsg(szMessage);
            inRetVal = VS_ERR;
            break;
        }
        /* Update the batch record for this transaction if approved */

        if (inRetVal == PIP_APPROVAL) {
            /* if 430 it is approved reversal and there is no batch record */
            if (!(Mti[0] == 0x04 && Mti[1] == 0x30)) {
                if (inModifyBatchRec(pobTran) != VS_SUCCESS) {
                    inRetVal = VS_ERR;
                    break;
                }
            }
        } else {
            /* Offline upload failed stop processing */
            if (fSettle == VS_FALSE)
                break;
            else {
                vdGetMessageFromThisFile(PIP_MESSAGE_FILE, ADVICE_UPLOAD_ERR_MSG, szMessage);
                strncat(szMessage, (char *) srISO.pszField39, FIELD39_SIZE);
                vdSGRespMsg(szMessage);
                inRetVal = VS_ERR;
                break;
            }
        }
        /* NEED not check for MaxAdvice, loop continously */
        if (fSettle == VS_TRUE) {
            inMaxAdvices = 2;  /* Make sure you enter the loop again */
            continue;
        }
    } while (--inMaxAdvices > 0);  /* Continue till you get tired! */

    vdFreeISO8583Data(psrHostData);


    /* Restore reversal handling  */
    psrHostData->reverse_flag = (unsigned char) fGetReversal(pobTran);

    if ((inRetVal == VS_SUCCESS) || (inRetVal == VS_ERR))
        return(inRetVal);

    /* Result of offline advice upload processing */
    if ((fSettle == VS_TRUE) && (inRetVal != PIP_APPROVAL))
        return(VS_ERR);

    return(VS_SUCCESS);
}

/*-----------------------------------------------------------------------------
* Routine Name : void vdFormatDate(pchDate)
* Description  :Converts from YYMMDD to MM/DD/YY format if Date format = 0
*                else converts to DD/MM/YY format BUG235
* Inputs       : The TCT date format flag.
* Outputs      : Formatted date in pchDate as per the flag.
*                  if flag = 0  MM/DD/YY else DD/MM/YY.
* Notes        : Changed to convert to DD/MMM/YYYY or MMM/DD/YYYY format.
                 _kulk. 29/3/96.
*-----------------------------------------------------------------------------
*/
void vdFormatCITIDate(char* pchDate) {
    char szLocal[DATE_SIZE + 1];
    char szMonthNames[40];
    short Month;

    strcpy(szLocal, pchDate);
    Month = (szLocal[2] - '0') * 10 + (szLocal[3] - '0') - 1;
    strcpy(szMonthNames, "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC");
    if (szLocal[0] == '9')
        sprintf(pchDate, "%.2s/%.3s/19%.2s", &(szLocal[4]), &(szMonthNames[Month * 3]), szLocal);
    else
        sprintf(pchDate, "%.2s/%.3s/20%.2s", &(szLocal[4]), &(szMonthNames[Month * 3]), szLocal);
    pchDate[11] = NULL_CH;
}





int inCheckMultiBatchEmpty(TRANSACTION_OBJECT* pobTran) {
    int     /* inShift, AXAS_LINT_REMOVED */ inNewCurr,
    inReportTop = VS_TRUE;
    //char    chShift AXAS_LINT_REMOVED ;
    int inResult,
    inNeedGrTot,
    inCnt = 0;
    int inNeedCurrTot,
    inCurr = 0;
    int inNumberOfRecordsinBatch;
    int inPrintDetail = VS_FALSE;
    int inStart,
    inStop,
    inNumberOfMerchants,
    inMerch = 0;
    int inHostIndex;
    int inCurrencyFlag = VS_FALSE;
    long lnRecordKey;
    int inRecFound = 0;
    HDT_REC srTempHDTRec;

    /* Shift total accumulators */
    // DETAIL_TOTALS srShTot; AXAS_LINT_REMOVED
    /* Grand total accumulators */
    DETAIL_TOTALS srGrTot;
    /* Currency total accumulators */
    DETAIL_TOTALS srCurrTot;



    if (fChkAllHostBatches(pobTran)) {
        vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
        return(VS_SUCCESS);
    }

    /* determine how many merchants should be printed */
    inNumberOfMerchants = inSelectOneAllMID(pobTran, fGetMultiMerchPrompt());//CPAC1.2B
    if (inNumberOfMerchants == 0)
        return(VS_SUCCESS);
    if (inNumberOfMerchants == inGetMITTotRecs()) {
        inStart = 1;
        inStop = inGetMITTotRecs();
    } else if (inNumberOfMerchants == 1) {
        inStart = inGetMerchantNum();//CPAC2.1B
        inStop = inGetMerchantNum();//CPAC2.1B
    } else {
        inStart = 1;
        inStop = 0;
    }


    inHostIndex = shGetHostGroupRef();

    if (inLoadConfRec(HDT_FILE_NAME, SIZE_HDT_REC, inHostIndex, (char *) &srTempHDTRec) != VS_SUCCESS) {
        vdSGErrorMessage(HDT_ERR_MSG21);
        return(VS_ERR); //added int to return.
    }
    if (fGetAllowMultiCurrency())//CPAC2.1B
        inCurrencyFlag = VS_TRUE;


    for (inMerch = inStart; inMerch <= inStop; inMerch++) {
        if (inLoadMITRec(inMerch - 1) != VS_SUCCESS)
            return(VS_ERR);

        inZeroDetailTotals(&srGrTot);
        inNeedGrTot = 0;  /* bb1 */

        inNumberOfRecordsinBatch = inGetDCBatchRecCnt(pobTran);
        /* Check whether the batch is empty or not */
        if (inNumberOfRecordsinBatch == 0) {
            vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);


            //vdDisplayMessageFromFile( SKIP_MSG, STATUS_MSG);
            vdCloseDCBatch(pobTran); /* bb1 */
            return(VS_ERR);
        } else /* bb1 */ {
            /* bb1 */


            //inPrintReportHeader(pobTran, obPrinter);
            inNeedCurrTot = 0;
            for (inCurr = 0; inCurr < inGetCSTTotRecs(); inCurr++) {
                if (inLoadCSTRec(inCurr) != VS_SUCCESS) {
                    vdSGErrorMessage(CST_ERR_MSG);
                    return(VS_ERR);
                }
                inCnt = 0;
                inZeroDetailTotals(&srCurrTot);
                pobTran->srBKey.inCurrencyIndex = inCurr;

                inNewCurr = VS_TRUE;


                /* Print online records */
                lnRecordKey = DB_FIRST;
                do {
                    if ((inResult = inGetDCKeyBatchRec(pobTran, KEY_CURRENCY, &pobTran->srBKey, lnRecordKey)) != VS_EOB) {
                        inLoadCDTRec(pobTran->srBRec.inCDTIndex);
                        /*                      if(inGetCDTHostIndex() != inHostIndex) sadiq 1.4 changed */
                        if (inGetHostHandle() != inHostIndex) {
                            lnRecordKey = DB_NEXT;
                            //inRecFound=1;
                            continue;
                        }
                        if (inGGCode() != AUTH_ONLY && inGGCode() != IMAM_CARDVER) {
                            inRecFound = 1;
                            if (inNewCurr) {
                                inNewCurr = VS_FALSE;
                                /* Header condition should not print report title except at top of report */

                                inReportTop = VS_FALSE;
                            }


                            inCnt++;

                            // if (act_kbd_pending_test(KEY_CANCEL))
                            //    return(VS_ESCAPE);
                        }
                    }   /* end of key */
                    lnRecordKey = DB_NEXT;
                } while (inResult != VS_EOB);

                if (inRecFound == 0) {
                    vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
                    vdSGErrorMessage(BATCH_EMPTY_MSG);
                    return(VS_ERR);
                }
                /* Bottom */
                if (inCnt > 0) {
                    if (inGetCSTTotRecs() > 1 && inCurrencyFlag == VS_TRUE)
                        inNeedCurrTot++;
                    else
                        inNeedGrTot++;
                }
            }/* end currency for loop */


            vdCloseDCBatch(pobTran); /* bb1 */
        } /* bb1 */
    } /* merchant loop */
    if (inLoadHDTRec(inHostIndex) != VS_SUCCESS) {
        //CPAC2.1B
        vdSGErrorMessage(HDT_ERR_MSG21);
        return(VS_ERR); //changed from empty return.
    }

    if (inRecFound == 0) {
        vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
        vdSGErrorMessage(BATCH_EMPTY_MSG);
        return(VS_ERR);
    }

    return (VS_SUCCESS);
}



int inUpdateOfflineAccum(TRANSACTION_OBJECT* pobTran,ACCUM_VALUES* psrAccum) {
#ifndef IMAM_REMOVE
#if 0
    if (inGGCode()==SALE_OFFLINE){
        if (pobTran->srTRTRec.TransactionCode == ADJUST)
        {
            psrAccum->lnCustom2+=pobTran->srBKey.lnTotalOfTransactionAmount;
            psrAccum->lnCustom2-=pobTran->srBRec.lnOldTotalTransactionAmount;
        }
        else if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE)
        {
            psrAccum->lnCustom1-=1;
            psrAccum->lnCustom2-=pobTran->srBKey.lnTotalOfTransactionAmount;
        }
        else  {
            psrAccum->lnCustom1+=1;
            psrAccum->lnCustom2+=pobTran->srBKey.lnTotalOfTransactionAmount;
        }
    /* if (pobTran->srBKey.fVoided) {
        psrAccum->lnCustom1-=1;
        psrAccum->lnCustom2-=pobTran->srBKey.lnTotalOfTransactionAmount;
    }
     else {
        psrAccum->lnCustom1+=1;
        psrAccum->lnCustom2+=pobTran->srBKey.lnTotalOfTransactionAmount;
       }  */
    }
#endif /* 0 */
    switch (inGGCode()) {
    case SALE_OFFLINE :
        switch (pobTran->inTransactionCode) {
        case SALE_OFFLINE :
            psrAccum->dbCustom1 += 1;
            psrAccum->dbCustom2 += pobTran->srBKey.lnTotalOfTransactionAmount;
            break;
        case ADJUST      :
        case CPAC_PHIL_ADJUST:
            /* 1.4_citiphil_don_26feb_DSC_??? */
            psrAccum->dbCustom2 += pobTran->srBKey.lnTotalOfTransactionAmount;
            psrAccum->dbCustom2 -= pobTran->srBRec.lnOldTotalTransactionAmount;
            break;
        case VOID       :
            psrAccum->dbCustom1 -= 1;
            psrAccum->dbCustom2 -= pobTran->srBKey.lnTotalOfTransactionAmount;
            break;
        case TIP_ADJUST :
            psrAccum->dbCustom2 += pobTran->srBKey.lnTotalOfTransactionAmount;
            //psrAccum->lnCustom2+=pobTran->srBRec.lnTipAmount;
            //psrAccum->lnCustom2-=pobTran->srBRec.lnTipAmount;
            psrAccum->dbCustom2 -= pobTran->srBRec.lnOldTotalTransactionAmount;
            break;
        default :
            break;
        }
        /*  case ADJUST      :
                                psrAccum->lnCustom2+=pobTran->srBKey.lnTotalOfTransactionAmount;
                                psrAccum->lnCustom2-=pobTran->srBRec.lnOldTotalTransactionAmount;
                                break;
                case VOID       :
                                psrAccum->lnCustom1-=1;
                                psrAccum->lnCustom2-=pobTran->srBKey.lnTotalOfTransactionAmount;
                                break;
                case TIP_ADJUST :
                                psrAccum->lnCustom2+=pobTran->srBKey.lnTotalOfTransactionAmount;
                                psrAccum->lnCustom2-=pobTran->srBRec.lnOldTotalTransactionAmount;
                                break;*/
    default :
        break;
    }
#endif //IMAM_REMOVE
    return(VS_SUCCESS);
}



/*********************************************************************************************
* @func void | vdLoadHostParams |
* Load the Network Internation ID  - ISO Field # 24
*
* @parm CPAC_REC * | psrCPACRec |
*       CPAC Host data record
*
* @end
**********************************************************************************************/

void vdLoadHostParams(CPAC_REC* psrCPAC,char* szHostName) {
    char szHDTLocalHostFileName[HOST_NAME_SIZE + 1];

    strcpy(szHDTLocalHostFileName, szHostName);
    vdTrimSpaces(szHDTLocalHostFileName);
    strcat(szHDTLocalHostFileName, ".dat");

    if (inLoadConfRec(szHDTLocalHostFileName, sizeof(CPAC_REC), 0, (char *) psrCPAC) != VS_SUCCESS) {
        vdSGErrorMessage(HDT_ERR_MSG21);
        return;
    }
}

#ifdef CITI_PHIL

static int inPhilDefaultRetrieveBatchInv(TRANSACTION_OBJECT* pobTran,int     (*pfGetXXKeyBatchRec) (TRANSACTION_OBJECT *, int, BATCH_KEY *, long),int                 (*pfGetXXInvBatchRec) (TRANSACTION_OBJECT *, int, long))
    //TRANSACTION_OBJECT *pobTran;
    //int                 (*pfGetXXKeyBatchRec)(TRANSACTION_OBJECT *, int, BATCH_KEY *, long);
    //int                 (*pfGetXXInvBatchRec)(TRANSACTION_OBJECT *, int, long);
{
    long lnMsg;
    long lnDBWhat = DB_FIRST;
    int inRetVal;
    char* chNull = 0;

    if (!pfGetXXKeyBatchRec)
        return(VS_ESCAPE);  /* "inGetXXKeyBatchRec" not defined */
    if (!pfGetXXInvBatchRec)
        return(VS_ESCAPE);  /* "inGetXXInvBatchRec" not defined */



    for (; ;) {
        pobTran->srBSKey.inKeyIdx = KEY_INV_NUM;
        if ((inRetVal = inGetInvoiceNumber(pobTran)) != VS_SUCCESS) {
            inRetVal = VS_ERR;
            break;
        }
        /*  1)  Retrieve the record in the batch with a specific invoice #
                    2)  Retrieve the last record in the chain if the record found belongs to a linked list
                */
        if ((inRetVal = pfGetXXInvBatchRec(pobTran, KEY_INV_NUM, lnDBWhat)) != VS_SUCCESS) {
            vdDisplayErrorMessage(NO_MATCH_MSG21);
            continue;
        }

        inRetVal = inRunFunction(pobTran, CPAC_CHK_INV_NUM);
        if (inRetVal != VS_SUCCESS)
            continue;

        if ((lnMsg = lnValidateVoidsAndAdjusts(pobTran)) == 0L)
            break;
        else
            vdDisplayErrorMessage(lnMsg);
    }




    return(inRetVal);
}


static int (*inPhilRetrieveBatchInv)(TRANSACTION_OBJECT*,int (*) (TRANSACTION_OBJECT *, int, BATCH_KEY *, long),int (*) (TRANSACTION_OBJECT *, int, long))   =  inPhilDefaultRetrieveBatchInv;


int inPhilUserChoice(TRANSACTION_OBJECT* pobTran) {
    return (inPhilRetrieveBatchInv(pobTran, inGetDCKeyBatchRec, inGetDCInvBatchRec));
}

/*********************************************************************************************
* @func int | inCPACSettleOperation |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/

int inCPACSettleOperation(TRANSACTION_OBJECT* pobTran) {
    int inCnt,
    inResult,
    inResultSum = 0;
    long lnResult;
    char szDummyMessage[MESSAGE_SIZE + 1];
    char szMerchantName[MESSAGE_SIZE + 1];
    char szHostName[HOST_NAME_SIZE + 1];
    char szEmptyStr[2];

    int inMerchs = inGetMITTotRecs();
    int inStart,
    inStop,
    inNumberOfMerchants,
    inMerch = 0;
    VS_BOOL fSettleMerch[MAX_MERCHS + 1];
    int inHosts = MAX_HOSTS; //CPAC2.1B
    inGlobalMerchantHandle = inGetMerchantNum();


    /* Set power failure recovery state */
    inPFRStateStoreAll(PFR_BEGIN_SETTLEMENT, pobTran, 1, 1);

    /**/pdebug(("--inSettleOperation--"));/**/

    memset(szMerchantName, 0, sizeof(szMerchantName));

    if (fGetDemoMode() && !fGetTrainSettle()) //CPAC2.1B
    {
        vdDisplayNoSettleMsg(TRAINING_DEMO_MODE_MSG21);
        /* Set power failure recovery state */

        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(VS_ERR);
    }

    /*Praveen_20/01/2003_To fix Must Settle Soon flag bug*/
    if (fChkAllHostBatches(pobTran)) {
        vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(VS_SUCCESS);
    }
    /* determine how many merchants should be settled */
    inNumberOfMerchants = inSelectOneAllMID(pobTran, fGetMultiMerchPrompt());//CPAC2.1B
    if (inNumberOfMerchants == inMerchs) {
        inStart = 1;
        inStop = inMerchs;
    } else if (inNumberOfMerchants == 1) {
        inStart = inGetMerchantNum();//CPAC2.1B
        inStop = inGetMerchantNum();//CPAC2.1B;
    } else {
        inStart = 1;
        inStop = 0;
    }

    inGlobalHostHandle = inGetHostHandle(); //LENIN

    vdSetMerchantNum(inGlobalMerchantHandle);
    /**/pdebug(("inStart = %d, inStop = %d", inStart, inStop));/**/
    inMerch = inGetMerchantNum();//CPAC2.1B
    /* loop for selected merchant(s) */
    //  for (inMerch = inStart; inMerch <= inStop; inMerch++)
    //  {

    if (inLoadMITRec(inMerch - 1) != VS_SUCCESS) {
        /**/pdebug(("inLoadMITRec"));/**/
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(VS_ERR);
    }

    if ((inResult = inSettleOpenTabs(pobTran)) != VS_SUCCESS) {
        /**/pdebug(("inSettleOpenTabs"));/**/
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        if (inResult == VS_ESCAPE) {
            fSettleMerch[inMerch] = VS_FALSE; // do not settle this merchant
            //continue;
        } else
            return(VS_ERR);
    } else
        fSettleMerch[inMerch] = VS_TRUE;


    /*
     *      Settle all hosts
     */
    /* ====================================================================*/
    /*  for (inCnt = 0; inCnt < inHosts; inCnt++)
        {
            if ( !fIsIndependentBatch ( inCnt ) )
             {
                continue;
             } */// LENIN MULTI HOST

    //vdDisplayMessageFromFile( CONFIRM_MSG, STATUS_MSG);
    vdGetMessageFromFile(CONFIRM_MSG15, szDummyMessage);

    vdGetMessageFromFile(EMPTY_STR_ERR_MSG, szEmptyStr);
    strcat(szDummyMessage, szEmptyStr);

    //          vdSetHostHandle(inCnt);
    inCnt = inGetHostHandle();
    if ((inResult = inLoadDefaultHost(inCnt)) != VS_SUCCESS) {
        /**/pdebug(("inLoadDefaultHost"));/**/
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(inResult);
    }
    if ((inResult = inLoadDefaultCurrency(pobTran)) != VS_SUCCESS) {
        /**/pdebug(("inLoadDefaultCurrency"));/**/
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(inResult);
    }

    strcpy(szHostName, szGetHostName());//CPAC2.1B

    lnResult = lnProceedWithSettlement(pobTran);
    if (lnResult == (long) VS_SUCCESS) {
        vdClearNonTitleLines();
        if (inStop > inStart) {
            // strcpy (szMerchantName, szGetMerchantText()); //CPAC2.1B Commented because Merchant name should not be displayed during Auto Settlemet(Saritha_b1)
            if (getgrid() == 0) {
                //Kelvin_F2 --- start: display merchant name without affect the title
                //vdDisplayDataStr(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR, ML_CENTER);
                vdDisplayDataStr(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR, ML_RIGHT);
                //Kelvin_F2 --- end: display merchant name without affect the title
            } else
                vdDispStrCentered(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR);
        }
        if (getgrid() == 0) {
            vdDisplayStatusString(szDummyMessage);
            vdDisplayDataStr(szHostName, (obDisp.inStatusLine * 2), CLR_EOL, ML_RIGHT);
        } else {
            strcat(szDummyMessage, szHostName);
            vdDisplayStatusString(szDummyMessage);
        }
        //              vdDelay(PROMPT_DELAY); cpac_2.2a removed the delay
        //vdSGAutoSettle(VS_TRUE) ;
        pobTran->fAutoSettle = VS_FALSE;
        if ((inResult = inConfirmSettle(pobTran)) != VS_SUCCESS) {
            /* Set power failure recovery state */
            inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
            return(inResult);
        }
    } else if (lnResult == BATCH_EMPTY_MSG) {
        //vdDisplayMessageFromFile( SKIP_MSG, WARNING_MSG);
    } else
        inResultSum++;
    vdCloseDCBatch(pobTran);
    // LENIN MULTI HOST    }

    /* ==================================================================== */

    //} /* merchant loop */


    // LENIN  for (inMerch = inStart; inMerch <= inStop; inMerch++)
    // LENIN {
    /**/pdebug(("inMerch = %d", inMerch));/**/
    // LENIN if (fSettleMerch[inMerch] == VS_FALSE)
    //  LENIN continue;

    if (inLoadMITRec(inMerch - 1) != VS_SUCCESS) // -2 LENIN
    {
        /**/pdebug(("inLoadMITRec"));/**/
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(VS_ERR);
    }

    vdClearNonTitleLines();
    if (inStop > inStart) {
        strcpy(szMerchantName, szGetMerchantText()); //CPAC2.1B
        if (getgrid() == 0)
            vdDisplayDataStr(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR, ML_RIGHT);
        else
            vdDispStrCentered(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR);
    }

    inResult = pCPACSettleAllHosts(pobTran);
    /**/pdebug(("pSettleAllHosts, inResult = %d", inResult));/**/

    // LENIN }

    /* Reset execute ZID download after successful settlement of all hosts */
    if (inResult == VS_SUCCESS) {
        if (inGetZIDdownload() == 1)
            inResult = inCallZontalk('F');
        else if (inGetZIDdownload() == 2)
            inResult = inCallZontalk('P');
    } else if (inResult == VS_FAILURE) /* not all hosts settle sucessfully, but some did */
        inResult = VS_SUCCESS;

    /* Add code to display the host response if no printer */
    /* 0 == NOPRINTER; don't include entire header just for 1 value... */
    /* if (inGetTCTPrinterType() == NOPRINTER) */
    if (!fGetEnablePrinter() || (inGetPrinterType() == 0)) {
        vdGGRespMsg(szDummyMessage);
        vdDisplayResponseString(szDummyMessage);
    }

    /* Set power failure recovery state */
    inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
    vdSGErrorMessage(0L);
    return(inResult);
}
/*********************************************************************************************
* @func int | pCPACSettleAllHosts|
*
*               Uses the total number of records in the HDT table
*               and a for loop to settle each host
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int pCPACSettleAllHosts(TRANSACTION_OBJECT* pobTran) {
    int inCnt,
    inResult,
    inResultSum = 0;
    char szDummy[MESSAGE_SIZE + 1];
    char szHostName[HOST_NAME_SIZE + 1];
    int inHosts;

    /**/pdebug(("--pSettleAllHosts--"));/**/
    inHosts = MAX_HOSTS;
    /* Add 1 to loop counter for loyalty settle */

    /* for (inCnt = 0; inCnt < inHosts; inCnt++)
    {
        pdebug (("inCnt=%d",inCnt));
        if ( !fIsIndependentBatch ( inCnt ) )
           {
            continue;
           }
    LENIN MUTLI HOST */
    vdDisplayMessageFromFile(SETTLE_HOST_MSG, STATUS_MSG);
    vdGetMessageFromFile(SETTLE_HOST_MSG, szDummy);
    inCnt = inGetHostHandle(); //LENIN MULTI HOST
    vdSetHostHandle(inCnt);

    if ((inResult = inLoadDefaultHost(inCnt)) != VS_SUCCESS) {
        pdebug(("inLoadDefaultHost=%d", inResult));
        return(inResult);
    }

    if ((inResult = inLoadDefaultCurrency(pobTran)) != VS_SUCCESS) {
        pdebug(("inLoadDefaultCurrency=%d", inResult));
        return(inResult);
    }

    strcpy(szHostName, szGetHostName());//CPAC2.1B


    strcat(szDummy, szHostName);
    if ((get_font_mode() == 2) && (getgrid() == 0)) {
#ifndef TLFB
        char szTemp[10];
#else
        char szTemp[20];
#endif /* ifndef TLFB */

        char* ptr = strchr(szDummy, '-');
        memset(szTemp, NULL_CH, sizeof(szTemp)); //Kelvin_f2 make it clear before get the message (Saritha added)

#ifndef TLFB
        strncpy(szTemp, szDummy, ptr - szDummy);  // Looks strange


        vdDisplayAt(obDisp.inHomeCol, obDisp.inStatusLine, szTemp, CLR_EOL);
        //Kelvin_F2 --- start: fix on "Settl-" in Chinese message
        //inMLDisplayAt( strlen( szTemp ), obDisp.inStatusLine, ptr,CLR_EOL, ML_USE_GIVEN_FONT,
        //      ML_MENU_FONT, ASC4X16_VFT );
        inMLDisplayAt((strlen(szTemp) + 1), obDisp.inStatusLine, ptr, CLR_EOL, ML_USE_GIVEN_FONT, ML_MENU_FONT, ASC4X16_VFT);
        //Kelvin_F2 --- end: fix on "Settl-" in Chinese message
#else
        inMLDisplayAt(10, 8, szHostName, CLR_EOL, ML_USE_GIVEN_FONT, ML_MENU_FONT, ASC8X21_VFT);
        // vdDisplayAt(obDisp.inHomeCol, obDisp.inStatusLine , szHostName, CLR_EOL);
#endif
    } else
        vdDisplayStatusString(szDummy);
    vdDelay(PROMPT_DELAY);

    vdSGCode(SETTLE); {
        long lnResult;

        lnResult = lnProceedWithSettlement(pobTran);
        if (lnResult == (long) VS_SUCCESS) {
            SVC_WAIT(2000);

            if (inCPACSettleAHost(pobTran) != VS_SUCCESS)
                inResultSum++;
            /* Reset the Power failure state */
            inPFRStateStoreAll(PFR_BEGIN_SETTLEMENT, pobTran, 1, 1);
        } else if (lnResult == BATCH_EMPTY_MSG) {
            vdDisplayMessageFromFile(SKIP_MSG, WARNING_MSG);
		#ifndef  ICICI
            		inClrBatch (pobTran, CLEAR_HOST, VS_FALSE); /*Renu_fix_for_reversal*/
		#endif  /* ICICI */
        }
    }
    vdCloseDCBatch(pobTran);
    // LENIN MULTI HOSY }

    if (inResultSum > 0) {
        if ((fGGAutoSettle()) || (inResultSum == inHosts)) // auto settle or all hosts failed
            return(VS_ERR);
        else
            return(VS_FAILURE); /* not all host failed, but at least one did */
    }

    /* Reset invoice number after settlement, if all hosts settled successfully */
    /*  if ((inResult = inResetInvNum()) != VS_SUCCESS)
            vdDisplayMessageFromFile( BDT_ERR_MSG, ERROR_MSG); */

    return(VS_SUCCESS); /* all host settled successfully */
}


/*********************************************************************************************
* @func int | inCPACSettleAHost|
*
*               Calls the protocol functions to settle a specific host
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inCPACSettleAHost(TRANSACTION_OBJECT* pobTran) {
    int inResult = VS_ERR;
    int inSaveHostHandle;
    short fBatchUpload; //spqalog011
    char szDate[DATE_SIZE + 1],
    szTime[TIME_SIZE + 1];

    VS_BOOL fSettleSucceeded,
    fCommErr = VS_FALSE;

#ifdef  COUNTER_DEFINED
    COUNTER_OBJECT obCounter;
#endif  /* COUNTER_DEFINED */

    /**/pdebug(("--inSettleAHost--"));/**/

    /* Dont execute the following during PFR if power fails after this segment */
    if (vPFRSetPartFunc(__LINE__)) {
        memset(pobTran->szRespMsg, 0x00, RESP_MSG_SIZE);

        vdGetDate(szDate, MMDDYY);
        vdGetTime(szTime);
        strlcpy(pobTran->szSettTime, szTime, DATE_SIZE);
        strlcpy(pobTran->szSettDate, szDate, DATE_SIZE);

        inSaveHostHandle = inGetHostHandle();
        /*
             *      Open Batch for Settlement here, where we are sure proper host has already
             *      been loaded.
             */
        vdBatchDCOpen(pobTran);
        if ((fGetDemoMode() == VS_TRUE) && (fGetTrainSettle() == VS_TRUE)) {
            // CPAC2.1B
            inResult = inFakeSettle(pobTran);
            inResetDemoBatch(pobTran);
        } else {
#ifdef COUNTER_DEFINED
            inSetTimerOnOff(START_TIMER_3);
#endif  /* COUNTER_DEFINED */

            inResult = inRunSettleProtocolFunction(pobTran);

#ifdef COUNTER_DEFINED
            obCounter.inType = BATCH_SET_RESP_TIME;
            obCounter.inIndex = inGetHDTCounterIndex();
            inIncCounter(&obCounter, (int) (inSetTimerOnOff(STOP_TIMER_3)));
#endif  /* COUNTER_DEFINED */
        }


        if (inResult == VS_SUCCESS) {
            //            BT_TRACE ('I', "Settle Successful");
            vdDisplayMessageFromFile(SETTLE_SUCCESS_MSG, STATUS_MSG);
            fSettleSucceeded = VS_TRUE;
            vdSGErrorMessage(0L);
            /* vdSGErrorMessage(EMPTY_STR_ERR_MSG);*/
        } else {
            pdebug(("inPackUnpack=%d", inResult));
            /*
                     *      Settle Error Handling
                     *          Do not overwrite error set in host code
                     *          Always display SETTLE FAILED ERROR MESSAGE
                     */
            if (strlen(pobTran->szRespMsg) > 0) {
                //       BT_TRACE ('I', pobTran->szRespMsg);
            } else {
                //                BT_TRACE ('I', "Settle Failed");
            }

            if (lnGGErrorMessage() == TXMT_FAIL_ERR_MSG)
                fCommErr = VS_TRUE;

            if (!fGGAutoSettle()) /* removed single settle check */
		{

                	vdDisplayMessageFromFile(SETTLE_FAIL_ERR_MSG, WARNING_MSG);
                	ACTIVITY_LOG("Settle error - Run protocol");//citiphil_27feb_DSC_don
                	#ifdef ICICI
				/* Print Settle Failed Receipt */
				inPrintFailedSettlementMessage(pobTran, &obPrinter);
				/* Print Settle Failed Receipt */
			#endif  /*   ICICI  */
                SVC_WAIT(1000);
            }

            if (strlen(pobTran->szRespMsg) > 0)
                pad(pobTran->szRespMsg, pobTran->szRespMsg, ' ', MESSAGE_SIZE, CENTER);
            fSettleSucceeded = VS_FALSE;
        }

        /* In case the HDT record was changd during host settlement reset the HDT Table */

        if (inLoadHostData(inSaveHostHandle) != VS_SUCCESS)
            return(VS_ERR);

        inMakeTerminalTotals(pobTran, VS_FALSE, fSettleSucceeded);
        /** /pdebug(("fSettleSucceeded = %d", fSettleSucceeded));*/
    }// if (vPFRSetPartFunc(__LINE__)
    else {
        /* Because we have just recovered, the batch is set as OPEN in trans object */
        pobTran->fBatchOpen = VS_FALSE;
        vdBatchDCOpen(pobTran);
        fSettleSucceeded = VS_TRUE;
        /* Need to retrieve local variable to indicate settlement succeeded */
        inGetExternalPfrData(PFR_SETTLE_SUCCEED, (unsigned char *) &fSettleSucceeded, sizeof(VS_BOOL));
    }


    /* Need to store local variable to indicate settlement succeeded */
    inAddExternalPfrData(PFR_SETTLE_SUCCEED, (unsigned char *) &fSettleSucceeded, sizeof(VS_BOOL));

    /* If we fail at this point, then the above segment will be skipped */
    inPFRStateStoreAll(PFR_BEGIN_SETTLE_REPORT, pobTran, 1, 1);


    // inPrintSettlementReport(pobTran, VS_FALSE, fSettleSucceeded, fCommErr);

    if (fSettleSucceeded) {
        SETT_REC srLocSRec;
        SETT_KEY srLocSKey;
        //spqalog011
      // Used to fix Batch Number increment during Settlement with Batch Upload jzg 05-Mar-05
        inGetTranFlexiData(pobTran, CITI_BATCH_UPLOAD_FLAG, (unsigned char *) &fBatchUpload, 2);

        if (fBatchUpload==1)
        {
	// end-of-update
	//To fix the batch number increment issue...moved this from inReconcileCPAC
	  		if (inResetBatch(pobTran) != VS_SUCCESS)
                return(VS_ERR);
        }
        inPrintSettlementReport(pobTran, VS_FALSE, fSettleSucceeded, fCommErr);
        /* pj1 Add host name to sett_rec and set GDS*/
        inMakeTerminalTotals(pobTran, VS_FALSE, fSettleSucceeded); //CPAC2.2B
        strcpy(srRcpt.szHostName, szGetHostName());
        strcpy(srLocSRec.szHostName, srRcpt.szHostName);
        inPutSettRec(pobTran, &srLocSRec, &srLocSKey);
        //  inBackupAccum();
        /* if auto settlement do not show messages */
        if (fGGAutoSettle())
            inPurgeHostFromBatch(pobTran, inGetBatchIndex(), VS_FALSE);
        else
            inPurgeHostFromBatch(pobTran, inGetBatchIndex(), VS_TRUE);
        /* Delete open tab batch, formally done in inCheckOpenTabs() */
        //if ( inDeleteOpenTabBatch(pobTran) != VS_SUCCESS )   Saritha_b1 Opten tab batch is being deleted bug fixing.
        //vdDisplayMessageFromFile( SUSPEND_ERROR_MSG, ERROR_MSG);  Saritha_b1 Opten tab batch is being deleted bug fixing.

        /* Reset Offline count after settlement */
        if ((inResult = inResetOfflineCount()) != VS_SUCCESS)
            vdDisplayMessageFromFile(BDT_ERR_MSG, ERROR_MSG);

        if ((inResult = inResetAccum()) != VS_SUCCESS)
            vdDisplayMessageFromFile(ACCUM_ERR_MSG, ERROR_MSG);

#ifdef CLERK_DEFINED
        if ((inResult = inResetUTT(pobTran)) != VS_SUCCESS)
            vdDisplayMessageFromFile(UTT_FAIL_ERR_MSG21, ERROR_MSG);

        /* reset active clerk file bb1 */
        if ((inResult = inResetADT()) != VS_SUCCESS)
            vdDisplayMessageFromFile(ADT_FILE_ERR_MSG21, ERROR_MSG);

        inResetUDTLogedIn();
#endif /* if CLERK_DEFINED */

        /* Zero the STT File */
#ifdef SHIFT_DEFINED
        if (inResetSTT(pobTran) != VS_SUCCESS)
            vdDisplayMessageFromFile(STT_FAIL_ERR_MSG21, ERROR_MSG);
#endif
    }

    /*
     *      Must close the batch so that if this function is called again for a different host the correct
     *      batch will be opened above.
     */
    vdCloseDCBatch(pobTran);
    vdFree((char *) pobTran->srBRec.pchHostData);
    pobTran->srBRec.pchHostData = NULL;

    return(inResult);
} /* End of inSettleAHost () */

#endif /* CITI_PHIL */
#ifdef CITI_IND
/*-------------------------------------------------------------------------
    Function :    inCITIGetBatchNumber
    Description : This function checks if there is transaction record
                  corresponding to an invoice number exists in the Batch.
                  Called in the VOID/ADJUST transaction flow.
    Parameters :
    Returns :
    Notes :
--------------------------------------------------------------------------*/

int inCITIGetBatchNumber(TRANSACTION_OBJECT* pobTran) {
    char szBatchNumber[BATCH_NUM_SIZE + 1];
    char szLocBuf[1 + 1];
    int inResult;
    SETT_REC srLocSRec;
    SETT_KEY srLocSKey;
    int inRowLim = inGetRowLim();

    szBatchNumber[0] = '\0';
    memset(szLocBuf, NULL_CH, sizeof(szLocBuf));


    while (TRUE) {
        inResult = inEnterWithMessage(BATCH_NUM_MSG, SCROLL_DISPLAY_FALSE, szBatchNumber, INPUT_NUMS, inGetBatchNumSize(), inValidateString);
        window(obDisp.inHomeCol, obDisp.inTitleLine, inRowLim, obDisp.inCharsPerColumn);

        if (gu_clr_state())
            return(VS_ESCAPE);
        if (inResult <= 0) {
            vdSGErrorMessage(TXN_CANCELLED);
            return (VS_ERR);
        }

        strcpy(pobTran->szBatchNum, szBatchNumber);
        pad(pobTran->szBatchNum, pobTran->szBatchNum, '0', inGetBatchNumSize(), RIGHT);

        strlcpy(pobTran->szSettDate, szLocBuf, DATE_SIZE);
        if (inGetBatchNumSettRec(pobTran, &srLocSRec, &srLocSKey) != VS_SUCCESS) {
            vdDisplayNoDataMsg();
            continue;
        }
        return (VS_SUCCESS);
    }
}

/*-------------------------------------------------------------------------
    Function :    inCITIGetSettDate
    Description : This function checks if there is transaction record
                  corresponding to an invoice number exists in the Batch.
                  Called in the VOID/ADJUST transaction flow.
    Parameters :
    Returns :
    Notes :
--------------------------------------------------------------------------*/

int inCITIGetSettDate(TRANSACTION_OBJECT* pobTran) {
    char szSettDate[DATE_SIZE + 1],
    szScratch[DATE_SIZE + 1] ;
    int inResult;
    int inRowLim = inGetRowLim();

    /* Get settlement date */

    szSettDate[0] = '\0';

    vdSetNextLineEntry();

    inResult = inEnterWithMessage(SETT_DATE_MSG, SCROLL_DISPLAY_FALSE, szSettDate, INPUT_NUMS, 6, inValidateOrigDate);

    vdClrNextLineEntry();

    window(obDisp.inHomeCol, obDisp.inTitleLine, inRowLim, obDisp.inCharsPerColumn);

    if (inResult == VS_ESCAPE)
        return (VS_ESCAPE);

    if (strlen(szSettDate) < 6) {
        vdSGErrorMessage(INVALID_ENTRY_MSG);
        return (VS_ERR);
    }

    pobTran->szBatchNum[0] = '\0';

    pad(szScratch, szSettDate, '0', DATE_SIZE, RIGHT);
    strcpy(szSettDate, szScratch);
    szSettDate[6] = '\0';
    memcpy(szSettDate, &szScratch[2], 2);
    memcpy(&szSettDate[2], &szScratch[0], 2);
    strlcpy(pobTran->szSettDate, szSettDate, DATE_SIZE);
    return (VS_SUCCESS);
}




int inGetAirlineCode(TRANSACTION_OBJECT* pobTran) {
    int inResult;
    char szAirlineCode[15];
    char szMsg[25];
    vdGetMessageFromFile(ENTER_AIRLINE_CODE_MSG, szMsg);
    vdDisplayAt(1, 5, szMsg, CLR_EOL);
    inResult = inCPACEnterWithMessage(SPACE_ONE, SCROLL_DISPLAY_FALSE, 6, 7, szAirlineCode, INPUT_NUMS, 13, NULL);


    return(VS_SUCCESS);
}
#endif /* CITI_IND */

/*********************************************************************************************
* @func int | inCPACGetCheckMID |
*       Prompts user to select a merchant and confirms the merchant is valid.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
* @flag int    |  VS_ERR, VS_ESCAPE or VS_SUCCESS
* @end
**********************************************************************************************/

int inCPACGetCheckMID(TRANSACTION_OBJECT* pobTran) {
    /****** Kelvin_F2 --- start: Multi-host chinese support *****/
    int inGrid;
    int inFontType;
    /****** Kelvin_F2 --- end: Multi-host chinese support *****/

    int inCnt,
    inNumOfMerch,
    inMerchNum;
    int inKey,
    inRetVal,
    inNumChars;
    int inOptCreated = 0;
    char szDisplayBuffer[MESSAGE_SIZE + 1];
    char szUserInput[MERCH_INDEX_SIZE + 1];
    char szLineBuf[4][MESSAGE_SIZE + 1];

    int inKeyPrev = KEY_e;
    int inKeyNext = KEY_f;
    int inKeyExit = KEY_h;
    int inKeySel = KEY_g;

    /** / pdebug(("--inGetCheckMID--")); */
    LOG_PRINTFF((0x08L, "CPAC_GET_CHECK_MID = inCPACGetCheckMID =========================="));
    memset(szDisplayBuffer, '\0', sizeof(szDisplayBuffer));
    memset(szUserInput, '\0', sizeof(szUserInput));
    inCnt = 0;
    inMerchNum = 0;
    inNumChars = 0;
    inNumOfMerch = inGetMITTotRecs();
	#ifdef  ICICI
    inLoadINIRec(0);
 shGetNoOfMerchants();
 #endif   /* ICICI  */
    /* load and display merchant, get user merchant selection */
    /* only load, display, and get response if more than one merchant */

#ifdef ICICI
     if (inNumOfMerch > 1 && shGetNoOfMerchants()>1)
#else
	if (inNumOfMerch > 1)
#endif  /* ICICI  */

    {
        do
        {
            if (inLoadMITRec(inCnt) != VS_SUCCESS)
                return(VS_ERR);

            sprintf(szDisplayBuffer, SUBSTITUTE_D, inGetMerchantNum());
            strcat(szDisplayBuffer, "=");

            /****** Kelvin_F2 --- start: Multi-host chinese support *****/
            inGrid = getgrid();
            inFontType = get_font_mode();

            if (inGrid == 0)  //16 0r 8 chars
            {
                //Chinese version
                inMLDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine, szDisplayBuffer, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
		
				memset(szDisplayBuffer, '\0', sizeof(szDisplayBuffer));
                inMLDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine + 2, szDisplayBuffer, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                strlcpy(szDisplayBuffer, szGetMerchantText(), MESSAGE_SIZE);//CPAC2.1B
                inMLDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine + 1, szDisplayBuffer, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
            } else {
                vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine, szDisplayBuffer, CLR_EOL);
		 LOG_PRINTFF((0x08L, "CPAC_GET_CHECK_MID DSP 1%s",szDisplayBuffer));		
                memset(szDisplayBuffer, '\0', sizeof(szDisplayBuffer));
                vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine + 2, szDisplayBuffer, CLR_EOL);
		LOG_PRINTFF((0x08L, "CPAC_GET_CHECK_MID DSP 2%s",szDisplayBuffer))
		strlcpy(szDisplayBuffer, szGetMerchantText(), MESSAGE_SIZE);//CPAC2.1B
                vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine + 1, szDisplayBuffer, CLR_EOL);
		LOG_PRINTFF((0x08L, "CPAC_GET_CHECK_MID DSP 3%s",szDisplayBuffer))
            }

            //************* Original Coding ************
            //          vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine, szDisplayBuffer, CLR_EOL);
            //          memset(szDisplayBuffer,'\0',sizeof(szDisplayBuffer));
            //          vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine+4, szDisplayBuffer, CLR_EOL);
            //          vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine+2, szDisplayBuffer, CLR_EOL);
            //          strlcpy(szDisplayBuffer, srMITRec.szMerchantName, MESSAGE_SIZE);
            //          vdDisplayAt(obDisp.inHomeCol, obDisp.inTablesInputLine+1, szDisplayBuffer, CLR_EOL);
            /****** Kelvin_F2 --- end: Multi-host chinese support *****/
            /* 3200: parse keys, display in right window */
            vdLoad3200Opt(szLineBuf, O3200_TBL_CHOOSE_KEYS_MSG);
            vdCreateOptWin3200(szLineBuf);
            inOptCreated = 1;

            do {
                /* get first character */
                inKey = inWaitKey(inGetIdleTimeOut());
                inNumChars = 1;

                /* if numeric key press, get second digit or ENTER */
                if ((inKey > KEY0) && (inKey <= KEY9)) {
                    /* store and display first character */
                    szUserInput[0] = inKey;
                    /****** Kelvin_F2 --- start: Multi-host chinese support *****/
                    if (inGrid == 0)  //16 0r 8 chars
                        inMLDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                    else
                        vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, CLR_EOL);
                    //******* Original Coding *******/
                    //                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine+4, szUserInput, CLR_EOL);
                    /****** Kelvin_F2 --- end: Multi-host chinese support *****/

                    do {
                        /* get second character */
                        inKey = inWaitKey(inGetIdleTimeOut());
                        inNumChars = 2;

                        switch (inKey) {
                        case KEY0:
                        case KEY1:
                        case KEY2:
                        case KEY3:
                        case KEY4:
                        case KEY5:
                        case KEY6:
                        case KEY7:
                        case KEY8:
                        case KEY9:
                            /* store and display second character */
                            szUserInput[1] = inKey;
                            /****** Kelvin_F2 --- start: Multi-host chinese support *****/
                            if (inGrid == 0)  //16 0r 8 chars
                                inMLDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                            else
                                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, CLR_EOL);
                            //******* Original Coding *******/
                            //                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine+4, szUserInput, CLR_EOL);
                            /****** Kelvin_F2 --- end: Multi-host chinese support *****/

                            do {
                                /* get third character */
                                inKey = inWaitKey(inGetIdleTimeOut());

                                while ((inKey != KEY_CR) && (inKey != KEY_CLR) && (inKey != KEY_BS) && (inKey != KEY_CANCEL)) {
                                    vdBeep();
                                    /* wait for another key */
                                    inKey = inWaitKey(inGetIdleTimeOut());
                                }

                                switch (inKey) {
                                case KEY_CR:
                                    /* confirm merchant number is valid */
                                    if ((atoi(szUserInput) > 0) && (atoi(szUserInput) <= inNumOfMerch)) {
                                        inMerchNum = atoi(szUserInput);
                                        inRetVal = VS_SUCCESS;
                                    } else {
                                        /* display "Invalid Merchant" ?? */
                                        memset(szUserInput, '\0', sizeof(szUserInput));
                                        /****** Kelvin_F2 --- start: Multi-host chinese support *****/
                                        if (inGrid == 0)  //16 0r 8 chars
                                            inMLDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                                        else
                                            vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, CLR_EOL);
                                        //******* Original Coding *******/
                                        //                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine+4, szUserInput, CLR_EOL);
                                        /****** Kelvin_F2 --- end: Multi-host chinese support *****/
                                        inNumChars = 0;
                                        vdBeep();
                                    }
                                    break;
                                case KEY_BS:
                                    szUserInput[1] = '\0';
                                    inNumChars = 1;
                                    /****** Kelvin_F2 --- start: Multi-host chinese support *****/
                                    if (inGrid == 0)  //16 0r 8 chars
                                        inMLDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                                    else
                                        vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, CLR_EOL);
                                    //******* Original Coding *******/
                                    //                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine+4, szUserInput, CLR_EOL);
                                    /****** Kelvin_F2 --- end: Multi-host chinese support *****/
                                    break;
                                case KEY_CLR:
                                case KEY_CANCEL:
                                    inMerchNum = VS_ESCAPE;
                                    inRetVal = VS_ESCAPE;
                                    break;
                                default:
                                    vdBeep();
                                }
                                if ((inNumChars == 1) || (inNumChars == 0))
                                    break;
                            } while (inMerchNum == 0);
                            break;
                        case KEY_CR:
                            /* confirm merchant number if valid */
                            if ((atoi(szUserInput) > 0) && (atoi(szUserInput) <= inNumOfMerch)) {
                                inMerchNum = atoi(szUserInput);
                                inRetVal = VS_SUCCESS;
                            } else {
                                /* display "Invalid Merchant" ?? */
                                memset(szUserInput, '\0', sizeof(szUserInput));
                                /****** Kelvin_F2 --- start: Multi-host chinese support *****/
                                if (inGrid == 0)  //16 0r 8 chars
                                    inMLDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                                else
                                    vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, CLR_EOL);
                                //******* Original Coding *******/
                                //                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine+4, szUserInput, CLR_EOL);
                                /****** Kelvin_F2 --- end: Multi-host chinese support *****/
                                inNumChars = 0;
                                vdBeep();
                            }
                            break;
                        case KEY_CANCEL:
                            inMerchNum = VS_ESCAPE;
                            inRetVal = VS_ESCAPE;
                            break;
                        case KEY_BS:
                            szUserInput[0] = '\0';
                            inNumChars = 0;
                            /****** Kelvin_F2 --- start: Multi-host chinese support *****/
				#ifdef IMAM_DBS			
                            if (inGrid == 0)  //16 0r 8 chars
                                inMLDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, NO_CLEAR, ML_USE_GIVEN_FONT, ML_ACTION_FONT, "F:ASC8X21.VFT");
                            else
                                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine + 4, szUserInput, CLR_EOL);
                            //******* Original Coding *******/
                            //                vdDisplayAt(obDisp.inHomeCol, obDisp.inDetailLine+4, szUserInput, CLR_EOL);
                            /****** Kelvin_F2 --- end: Multi-host chinese support *****/

				#endif			
                            break;
                        default:
                            vdBeep();
                        } /* switch in second char */
                        if (inNumChars == 0)
                            break;
                    } while (inMerchNum == 0);
                } else if (inKey == inKeyPrev) {
                    if (inCnt == 0)
                        inCnt = inNumOfMerch - 1;
                    else
                        inCnt = inCnt - 1;
                    inMerchNum = 0;
                    break;
                } else if (inKey == inKeyNext) {
                    if (inCnt == (inNumOfMerch - 1))
                        inCnt = 0;
                    else
                        inCnt = inCnt + 1;
                    inMerchNum = 0;
                    break;
                } else if ((inKey == inKeySel) || (inKey == KEY_CR)) {
                    inMerchNum = inCnt + 1;
                    inRetVal = VS_SUCCESS;
                } else if ((inKey == inKeyExit) || (inKey == KEY_CANCEL)) {
                    inMerchNum = VS_ESCAPE;
                    inRetVal = VS_ESCAPE;
                } else
                    vdBeep();
            } while (inMerchNum == 0);
        } while (inMerchNum == 0);
    }
    else
    {
        inMerchNum = 1;
        inRetVal = VS_SUCCESS;
    }

    /* clear display */
    vdClearNonTitleLines();
    if (inOptCreated)
        vdDestroyOptWin3200();

    if (inMerchNum != VS_ESCAPE) {
        vdSetMerchantNum(inMerchNum);
        inGlobalMerchantHandle = inMerchNum;
        if (inLoadMITRec(inMerchNum - 1) != VS_SUCCESS)
            return (VS_ERR);
    } else
        return (VS_ESCAPE);

    if (fGetMerchPWFlag())
        inRetVal = inGetMerchPassword(pobTran);

	LOG_PRINTFF((0x08L, "CPAC_GET_CHECK_MID = inCPACGetCheckMID ========================== CPAC_GET_CHECK_MID %d",inRetVal));
    return (inRetVal);
}

/********************************************************************************************************************

    This function determines if the Merchant has been enabled to access
    a particular Host

********************************************************************************************************************/

int inCPACGetMerchEnable(TRANSACTION_OBJECT* pobTran) {
LOG_PRINTFF((0x08L, "inCPACGetMerchEnable 1 "));
    if ((fCPACGetMerchEnable()) == VS_TRUE)
        return(VS_SUCCESS);
    else {
        vdDisplayMessageFromFile(MERCH_NOT_ALLOWED, ERROR_MSG);
        return(VS_ERR);
    }
}



VS_BOOL fCPACGetMerchEnable(void) {
    CPAC_REC srLocCPAC;

    vdLoadCPACParams(&srLocCPAC);


    return ((VS_BOOL) srLocCPAC.fMerchEnable);
}



/* Autosettlement saritha */

int inCPACAutoSettleOperation(TRANSACTION_OBJECT* pobTran) {
    long lnResult;
    char szDummyMessage[MESSAGE_SIZE + 1];
    char szMerchantName[MESSAGE_SIZE + 1];
    char szHostName[HOST_NAME_SIZE + 1];
    char szEmptyStr[2];
    int inResult,
    inNoOfMITRecs ;
    int inResultSum = 0;
    char szDummy[MESSAGE_SIZE + 1];
    int inHosts,
    inMerch = 0;
    VS_BOOL fSettleMerch[MAX_MERCHS + 1];


    inHosts = MAX_HOSTS;

    vdSetActionFont(); // Make sure we are in the action font. ss-test

    inPFRStateStoreAll(PFR_BEGIN_AUTO_SETTLEMENT, pobTran, 1, 1);

    /**/pdebug(("--inSettleOperation--"));/**/

    memset(szMerchantName, 0, sizeof(szMerchantName));

    if (fGetDemoMode() && !fGetTrainSettle()) {
        vdDisplayNoSettleMsg(TRAINING_DEMO_MODE_MSG21);
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        vdSGErrorMessage(0L);
        return(VS_ERR);
    }

    vdDisplayMessageFromFile(SETTLE_HOST_MSG, STATUS_MSG);
    vdGetMessageFromFile(SETTLE_HOST_MSG, szDummy);


    inGlobalHostHandle = inGetHostHandle(); //LENIN


    //if ((inResult = inSettleOpenTabs(pobTran)) != VS_SUCCESS)
    //{
    //  /**/pdebug(("inSettleOpenTabs"));/**/
    /* Set power failure recovery state */
    //inPFRStateStoreAll(PFR_IDLE_STATE,pobTran,0,0);
    //      if (inResult == VS_ESCAPE)
    //  {
    //  fSettleMerch[inMerch] = VS_FALSE; // do not settle this merchant
    //continue;
    //      }
    //  else
    //  return(VS_ERR);
    //  }
    //else


    fSettleMerch[inMerch] = VS_TRUE;

    vdGetMessageFromFile(CONFIRM_MSG15, szDummyMessage);
    vdGetMessageFromFile(EMPTY_STR_ERR_MSG, szEmptyStr);
    strcat(szDummyMessage, szEmptyStr);

    if (inLoadDefaultHost(inGlobalHostHandle) != VS_SUCCESS)
        return (VS_ERR);

    if ((inResult = inLoadDefaultCurrency(pobTran)) != VS_SUCCESS) {
        /**/pdebug(("inLoadDefaultCurrency"));/**/
        /* Set power failure recovery state */
        inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
        return(inResult);
    }


    strcpy(szHostName, szGetHostName());//CPAC2.1

    lnResult = lnProceedWithSettlement(pobTran);

    if (lnResult == (long) VS_SUCCESS) {
        vdClearNonTitleLines();

        inNoOfMITRecs = inGetMITTotRecs();

        if (inNoOfMITRecs > 1)
            strcpy(szMerchantName, szGetMerchantText()); //CPAC2.1B  Commented because Merchant name should not be displayed during Auto Settlemet(Saritha_b1)

        if (getgrid() == 0) {
            //Kelvin_F2 --- start: display merchant name without affect the title
            //vdDisplayDataStr(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR, ML_CENTER);
            vdDisplayDataStr(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR, ML_CENTER);
            //Kelvin_F2 --- end: display merchant name without affect the title
            vdDisplayStatusString(szDummyMessage);
            vdDisplayDataStr(szHostName, (obDisp.inStatusLine * 2), CLR_EOL, ML_RIGHT);
        } else {
            vdDispStrCentered(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR);
            strcat(szDummyMessage, szHostName);
            vdDisplayStatusString(szDummyMessage);
        }
#if 0
            if (getgrid() == 0)
            {
                    vdDisplayStatusString(szDummyMessage);
                    vdDisplayDataStr(szHostName, (obDisp.inStatusLine * 2), CLR_EOL, ML_RIGHT);
            }
            else
            {
                    strcat(szDummyMessage,szHostName);
                    vdDisplayStatusString(szDummyMessage);
            }
#endif /* 0 */

        vdDelay(PROMPT_DELAY);
        pobTran->fAutoSettle = VS_TRUE;
        if ((inResult = inConfirmSettle(pobTran)) != VS_SUCCESS) {
            /* Set power failure recovery state */
            inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
            return(inResult);
        }
    } else if (lnResult == BATCH_EMPTY_MSG) {
        //vdDisplayMessageFromFile( SKIP_MSG, WARNING_MSG);
    } else
        inResultSum++;

    vdCloseDCBatch(pobTran);
    vdClearNonTitleLines();

    if (inNoOfMITRecs > 1)
        strcpy(szMerchantName, szGetMerchantText()); //CPAC2.1B Commented because Merchant name should not be displayed during Auto Settlemet(Saritha_b1)

    if (getgrid() == 0)
        vdDisplayDataStr(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR, ML_CENTER);
    else
        vdDispStrCentered(szMerchantName, (obDisp.inTitleLine + 1), NO_CLEAR);



    strcpy(szHostName, szGetHostName());//CPAC2.1B
    strcat(szDummy, szHostName);
    if ((get_font_mode() == 2) && (getgrid() == 0)) {
        char szTemp[10];
        char* ptr = strchr(szDummy, '-');

        strncpy(szTemp, szDummy, ptr - szDummy);
        vdDisplayAt(obDisp.inHomeCol, obDisp.inStatusLine, szTemp, CLR_EOL);
        //Kelvin_F2 --- start: fix on "Settl-" in Chinese message
        //inMLDisplayAt( strlen( szTemp ), obDisp.inStatusLine, ptr,CLR_EOL, ML_USE_GIVEN_FONT,
        //      ML_MENU_FONT, ASC4X16_VFT );
        inMLDisplayAt((strlen(szTemp) + 1), obDisp.inStatusLine, ptr, CLR_EOL, ML_USE_GIVEN_FONT, ML_MENU_FONT, ASC4X16_VFT);
        //Kelvin_F2 --- end: fix on "Settl-" in Chinese message
    } else
        vdDisplayStatusString(szDummy);


    vdSGCode(SETTLE); {
        long lnResult;

        lnResult = lnProceedWithSettlement(pobTran);
        if (lnResult == (long) VS_SUCCESS) {
            // SVC_WAIT(2000);

            if (inCPACSettleAHost(pobTran) != VS_SUCCESS)
                inResultSum++;
            /* Reset the Power failure state */
            inPFRStateStoreAll(PFR_BEGIN_AUTO_SETTLEMENT, pobTran, 1, 1);
        } else if (lnResult == BATCH_EMPTY_MSG) {
            vdDisplayMessageFromFile(SKIP_MSG, WARNING_MSG);
            inClrBatch(pobTran, CLEAR_HOST, VS_FALSE);
            vdSGErrorMessage(0L);
        }
    }
    vdCloseDCBatch(pobTran);
    // LENIN MULTI HOSY }

    vdSetMenuFont(); //autosettle-back to menu font - ss-test

    if (inResultSum > 0) {
        if ((fGGAutoSettle()) || (inResultSum == inHosts)) // auto settle or all hosts failed
            return(VS_ERR);
        else
            return(VS_FAILURE); /* not all host failed, but at least one did */
    }


    if (inResult == VS_SUCCESS) {
        if (inGetZIDdownload() == 1)// CPAC2.1B
            inResult = inCallZontalk('F');
        else if (inGetZIDdownload() == 2)// CPAC2.1B
            inResult = inCallZontalk('P');
    } else if (inResult == VS_FAILURE) /* not all hosts settle sucessfully, but some did */
        inResult = VS_SUCCESS;

    /* Add code to display the host response if no printer */
    /* 0 == NOPRINTER; don't include entire header just for 1 value... */
    /* if (inGetTCTPrinterType() == NOPRINTER) */
    if (!fGetEnablePrinter() || (inGetPrinterType() == 0)) {
        vdGGRespMsg(szDummyMessage);
        vdDisplayResponseString(szDummyMessage);
    }

    /* Set power failure recovery state */
    inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);
    vdSGErrorMessage(0L);
    return(inResult);
}

/****************************************************************************************

//// This is similar to ChkAllHostBatches() but for only one merchant ////

*****************************************************************************************/
VS_BOOL fChkHostBatches(TRANSACTION_OBJECT* pobTran,int inCount) {
    VS_BOOL fIsBatchEmpty;

    /** /pdebug (("--fChkAllHostBatches--"));*/

#ifdef BATCH_DEFINED

    /** /pdebug (("inNoMITRecs = %d",inNoMITRecs));*/

    inLoadMITRec(inCount);
    fIsBatchEmpty = fBatchEmpty(pobTran, VS_TRUE);
    if (fIsBatchEmpty != VS_TRUE)
        return(VS_FALSE);  /* Batch Not empty */
/** /pdebug (("Batch Empty"));*/

#endif // BATCH_DEFINED

    return(VS_TRUE);  /* Batch empty */
}


/******************************************************************************************

 This Function is written for Auto Settle Function which invokes KEY_FUNC_2
 Event , which is mapped to Auto Settlement Operation

 ******************************************************************************************/


int inCPACKeyFunc2(TRANSACTION_OBJECT* pobTran) {
    static int looptime = 0;

    inGlobalAutoHandle = 0;

    looptime++;

    if (looptime == CPAC_AUTO_SETTLE_LOOK_UP_TIME) {
        looptime = 0;
        inGlobalAutoHandle = 1;
        return(inEventResponder(KEY_2));
    }
    return(BRANCH_EXIT);
}


/*********************************************************************************************

    Used during Power Failur Recovery Operation

*********************************************************************************************/


int inCPACSetSettleCode(TRANSACTION_OBJECT* pobTran) {
    inGlobalMerchantHandle = inGetMerchantNum();

    vdSGCode(SETTLE);

    return(VS_SUCCESS);
}


/****************************************************************************************


    This funtion performs Daily Payment feature


*****************************************************************************************/

int inDailyPayment(TRANSACTION_OBJECT* pobTran) {
    int inNoOfMITRecs,
    inNoOfHDTRecs,
    inMCnt,
    inHCnt;
    char szHostName[HOST_NAME_SIZE + 1];
    char szCPACDate[DATE_SIZE + 1],
    szDate[DATE_SIZE + 1],
    szAmt[AMT_SIZE + 1];

    inNoOfMITRecs = inGetMITTotRecs();
    inNoOfHDTRecs = inGetHDTTotRecs();

    for (inMCnt = 0; inMCnt < inNoOfMITRecs; inMCnt++) {
        inLoadMITRec(inMCnt);

        for (inHCnt = 0; inHCnt < inNoOfHDTRecs ; inHCnt++) {
            inLoadHDTRec(inHCnt);

            if ((fCPACGetMerchEnable()) == TRUE) {
                strcpy(szHostName, szGetHostName());//CPAC2.1B


                vdLoadCPACParams(&srCPAC);

                //  #if FUTURE

                vdGetCPACCurDate(szCPACDate);
                if (strlen(szCPACDate) != 0) {
                    vdGetDate(szDate, YYMMDD);
                    if (strcmp(szDate, szCPACDate) != 0) {
                        vdSetCPACCurDate(szDate);
                        sprintf(szAmt, "%06ld", 0L);
                        vdSetCPACPresentAmt(szAmt);
                        if (inSaveCPACRec(&srCPAC) != VS_SUCCESS)
                            return (VS_ERR);
                    }
                }
            }   // End of Merchant Enabled loop condition.
        }   // End of No. Of Hosts Count
    }   // End of no. Of Merchants Count

    return(VS_SUCCESS);
}

/***********************************************************************************************

    This functions checks if ht Idle LoopTIme has reached 1 Hr. in
    order to reset the PrezAmt to 0 if the terminal has not been reset
    for more then one day.

***********************************************************************************************/

int inCPACDailyPayment(TRANSACTION_OBJECT* pobTran) {
    static int inIdleLoopTimeOut = 0;


    ++inIdleLoopTimeOut;

    if (inIdleLoopTimeOut == 3600)
        inDailyPayment(pobTran);

    return(VS_SUCCESS);
}

//Kelvin_F2 --- start: CPACTRT new flags
/*********************************************************************************************
* @func VS_BOOL | fGetTRTf1 |
*       Get TRT Record Field f1 "Print Bank Copy flag"
*
* @parm VS_BOOL    |  TRT Record Field f1   |
*
* @end
**********************************************************************************************/

VS_BOOL fGetTRTf1(TRANSACTION_OBJECT* pobTran) {
    return (VS_BOOL) (pobTran->srTRTRec.f1);
}

/*********************************************************************************************
* @func void | vdSetTRTf1 |
*       Set TRT Record Field f1 "Print Bank Copy flag"
*
* @parm VS_BOOL    |  TRT Record Field f1   |
*
* @end
**********************************************************************************************/

void vdSetTRTf1(TRANSACTION_OBJECT* pobTran,VS_BOOL param) {
    pobTran->srTRTRec.f1 = param;
}

/*********************************************************************************************
* @func VS_BOOL | fGetTRTf2 |
*       Get TRT Record Field f2 "Print Customer Copy flag"
*
* @parm VS_BOOL    |  TRT Record Field f2   |
*
* @end
**********************************************************************************************/

VS_BOOL fGetTRTf2(TRANSACTION_OBJECT* pobTran) {
    return(VS_BOOL) (pobTran->srTRTRec.f2);
}

/*********************************************************************************************
* @func void | vdSetTRTf2 |
*       Set TRT Record Field f2 "Print Customer Copy flag"
*
* @parm VS_BOOL    |  TRT Record Field f2   |
*
* @end
**********************************************************************************************/

void vdSetTRTf2(TRANSACTION_OBJECT* pobTran,VS_BOOL param) {
    pobTran->srTRTRec.f2 = param;
}


/*********************************************************************************************
* @func VS_BOOL | fGetTRTf3 |
*       Get TRT Record Field f3  "Print Merchant Copy flag"
*
* @parm VS_BOOL    |  TRT Record Field f3   |
*
* @end
**********************************************************************************************/

VS_BOOL fGetTRTf3(TRANSACTION_OBJECT* pobTran) {
    return(VS_BOOL) (pobTran->srTRTRec.f3);
}

/*********************************************************************************************
* @func void | vdSetTRTf3 |
*       Set TRT Record Field f3  "Print Merchant Copy flag"
*
* @parm VS_BOOL    |  TRT Record Field f3   |
*
* @end
**********************************************************************************************/

void vdSetTRTf3(TRANSACTION_OBJECT* pobTran,VS_BOOL param) {
    pobTran->srTRTRec.f3 = param;
}

//Kelvin_F2 --- end: CPACTRT new flags

int inCPACDemo(TRANSACTION_OBJECT* pobTran) {
#ifndef IMAM_REMOVE
    int inRetVal = VS_SUCCESS;
#ifdef EMV_MODULE
    if (pobTran->inChipStatus == EMV_CARD)
        inRetVal = inEMVDemo(pobTran);
#endif
#ifdef VXEMVAPP
	if (pobTran->inChipStatus == EMV_CARD)
		 inRetVal=inDemoFunction(pobTran);
               //inRetVal=inVXEMVAPPDemo(pobTran);
#endif
    inRetVal = inDefaultDemoFunction(pobTran);
	return(inRetVal);
#endif //IMAM_REMOVE
    return(SUCCESS);
}


int inSetToMainMenu(TRANSACTION_OBJECT* pobTran) {
    vdSelectMenu(ROOT_MENU_ID);
    return(BRANCH_EXIT);
}


int inCPACSetMustSettleFlag(TRANSACTION_OBJECT* pobTran) {
    char pchBFName[FILENAME_SIZE + 1];

    vdGetMHTFileName(pchBFName);
    if (inLoadMHTRec(inGetHostHandle()) != VS_SUCCESS) {
        vdSGErrorMessage(MHT_ERR_MSG21);
        return(VS_ERR);
    }
    vdSetMustSettleFlag(VS_TRUE);

    if (inSaveMHTRec(inGetHostHandle()) != VS_SUCCESS) {
        vdSGErrorMessage(MHT_ERR_MSG21);
        return(VS_ERR);
    }
    return(VS_SUCCESS);
}

int inCPACTransNameDisplay(TRANSACTION_OBJECT* pobTran) {
    short inTranCode;

    inTranCode = pobTran->srTRTRec.TransactionCode;
#ifndef TLFB
    vdDisplayAt(1, 1, "                ", NO_CLEAR);
#endif
    if ((inTranCode == ADJUST) || (inTranCode == CPAC_PHIL_ADJUST)) {
        vdDispMsgAt(ADJUST_MSG6, 1, 1, CLR_EOL);
        return(VS_SUCCESS);
    }

    if (inTranCode == TIP_ADJUST) {
        vdDispMsgAt(ADD_TIP_OFFLINE_MSG, 1, 1, CLR_EOL);
        return(VS_SUCCESS);
    }
    if (inTranCode == PRE_COMP) {
        vdDispMsgAt(PRE_COMP_ITEM_MSG15, 1, 1, NO_CLEAR);
        return(VS_SUCCESS);
    }


    return(VS_SUCCESS);
}


int inCPACDisplayResponse(TRANSACTION_OBJECT* pobTran) {
    char szDispMsg[RESP_MSG_SIZE];
    //  int inChar, inGrid;


    if (fGetDemoMode()) /* Demo mode response message is handled in demo function */
        return (VS_SUCCESS);
    	  if(strcmp(pobTran->srBRec.szRespCode, "88") ==0)
  	{
 	strcpy(szDispMsg,"APPR,C/H CALL AMEX");
	vdDisplayStatusString(szDispMsg);
	vdDelay(500);
        vdCITINormalBeep(20);
	return(VS_SUCCESS);
  	}
   if(strcmp(pobTran->srBRec.szRespCode, "08") ==0)
  	{
 	strcpy(szDispMsg,"APPR,WITH SIGNATURE");
	vdDisplayStatusString(szDispMsg);
	vdDelay(500);
	 vdCITINormalBeep(20);
	return(VS_SUCCESS);
  	}



    vdGGRespMsg(szDispMsg); // Since we are printing whatever the host returns; has to be ASCII

    // Now display the approval code [APPROVED] nnnnnnn

    vdDisplayStatusString(szDispMsg);

    //   strcat(szDispMsg,"   ");
    strcpy(szDispMsg, pobTran->srBRec.szAuthCode);

	vdDisplayDataStr(szDispMsg, inImamLineNumber, CLR_EOL, ML_RIGHT);
    //  vdDisplayStatusString(szDispMsg);

	if (pobTran->srTRTRec.TransactionCode == AUTH_ONLY || pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) {  // for CardVer Permata
		if (!fGetPrintReceipt(pobTran)) {
			vdDisplayDataStr(" ", inImamLineNumber, CLR_EOL, ML_LEFT);
			//vdDisplayDataStr("APPROVED", 7, CLR_EOL, ML_LEFT);
			vdDisplayAt(1, inImamLineNumber-1, "APPROVED", CLR_EOL);
			vdDisplayDataStr(szDispMsg, inImamLineNumber-1, CLR_EOL, ML_RIGHT);
			(void) inWaitKey(inGetIdleTimeOut());
		}
	}

#if 0
    /* if transaction meets Fast Payment requirements and the Print Option is NONE,
        wait for key press or idle time out */
    if ((fFPSQualified(pobTran)) && (pobTran->srBRec.inPrintOption == PRT_NONE))
        (void) inWaitKey(inGetIdleTimeOut());

    if (inGetPrinterType() == NOPRINTER ||
          !fGetEnablePrinter()           ||
             !fGetPrintReceipt(pobTran)              )
    {
         vdFlushKeyboardBuffer();
            while(((inChar = get_char()) != KEY_CR) && inChar != KEY_CANCEL)
        vdBeep();
    }
#endif /* 0 */

	if (inGGCode() == DEBIT_BAL_INQ) {  //LIEM: to support BAL_INQ, NEED TO CHECK Field04 ???
		pobTran->srBRec.lnBaseTransactionAmount = strtol((char *)srISO.pszField04, NULL, 10);
		pobTran->srBKey.lnTotalOfTransactionAmount = pobTran->srBRec.lnBaseTransactionAmount;
		if(inGetCurrencyIdx()) {
		} else {
			pobTran->srBRec.lnBaseTransactionAmount = pobTran->srBRec.lnBaseTransactionAmount/100;
			pobTran->srBKey.lnTotalOfTransactionAmount = pobTran->srBKey.lnTotalOfTransactionAmount/100;
		}
	}

	if (inGGCode() == POINT_BAL_INQ) {  //LIEM: to support BAL_INQ, NEED TO CHECK Field04 ???
		pobTran->srBRec.lnBaseTransactionAmount = strtol((char *)srISO.pszField04, NULL, 10);
		pobTran->srBKey.lnTotalOfTransactionAmount = pobTran->srBRec.lnBaseTransactionAmount;
		if(inGetCurrencyIdx()) {
		} else {
			pobTran->srBRec.lnBaseTransactionAmount = pobTran->srBRec.lnBaseTransactionAmount/100;
			pobTran->srBKey.lnTotalOfTransactionAmount = pobTran->srBKey.lnTotalOfTransactionAmount/100;
		}
	}
#ifndef IMAM_BNI
	if (pobTran->srTRTRec.TransactionCode == SALE || pobTran->srTRTRec.TransactionCode == SALE_OFFLINE) {
		if (ImamActiveMenu->inDataID==3 || ImamActiveMenu->inDataID==11){
			int inRetval;
			strcpy(szDispMsg, pobTran->srBRec.szAuthCode);
			DisplayStatus("APPROVED");
			vdDisplayDataStr(szDispMsg, inImamLineNumber, CLR_EOL, ML_RIGHT);
		//	inRetval = inImamVivoPtSaleTopup(pobTran);
			
			if (inRetval != VS_SUCCESS){
				if (ImamActiveMenu->inDataID==11){
					inRunFunction(pobTran, RENAME_REVERSAL_FILE);
					return VS_ERROR;
				}
			}
			return inRetval;
			}
	}
	#endif
    return (VS_SUCCESS);
}


int inCPACPrintLineFeed(TRANSACTION_OBJECT* pobTran/*, PRINTER_OBJECT *obPrinter*/) {
    //extern short shSpool(PRINTER_OBJECT *obPrinter, char *szBuffer);

#if 0
    //inCPACPrintLines("               ", obPrinter);

    //inGetReport1Template();
    char szTemplateFileName[FILENAME_SIZE+1];
    //inLoadLCTRec(0);
    strcpy(szTemplateFileName, STATIC_DATA_PATH);
    strcat(szTemplateFileName, szGetLanguageNamePrefix() );
    //strcat( szTemplateFileName, "ENGL");
    strcat( szTemplateFileName, szGetTemplateFileNameSuffix());


    if (inSwitchTemplate(szTemplateFileName) < 0)
    {
        vdDisplayMessageFromFile( FORMATER_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
    //  inRunOperation (pobTran, PRINT_FORMFEEDS);
    }


#endif /* 0 */
    //vdFormFeed( &obPrinter );
    shSpool(&obPrinter, "\n\n\n\n\n\n");

    return (VS_SUCCESS);
}

int inCPACTipPercentValid(char* pchValue) {
    int inRetVal = VS_ERR;

    if ((strcmp(pchValue, "0")) == 0)
        inRetVal = VS_SUCCESS;
    else {
        if (inIsDigits(pchValue) && inRange(atoi(pchValue), 100, 10000))
            inRetVal = VS_SUCCESS;
        else
            vdDisplayMessageFromFile(CPAC_TIP_PERCENT_VALID_MSG, WARNING_MSG);
    }

    vdSGErrorMessage(0L);
    return (inRetVal);
}

int inCPACDispTransName(TRANSACTION_OBJECT* pobTran) {
    char Message[MESSAGE_SIZE + 1];

    if (pobTran->inOperationCode == BATCH_REVIEW_OPERATION) {
        if (pobTran->srBKey.fVoided == VS_TRUE)
            vdCPACGetMessageFromReceiptFile(VOID_MSG6, Message, pobTran);
        else {
            if (pobTran->srBRec.inNumberOfAdjusts > 0 || pobTran->srBRec.inNumberOfTipAdjusts > 0) {
                if (pobTran->srBRec.inNumberOfAdjusts > 0)
                    vdCPACGetMessageFromReceiptFile(ADJUST_MSG6, Message, pobTran);
                else if (pobTran->srBRec.inNumberOfTipAdjusts > 0)
                    vdCPACGetMessageFromReceiptFile(CPAC_TIP_ADJUST_MSG, Message, pobTran);
            }
        }
    } else {
        if (pobTran->inOperationCode == SETTLE_OPERATION)
            vdCPACGetMessageFromReceiptFile(SETTLE_MSG21, Message, pobTran);
        else {
            vdGetMessageFromFile(pobTran->srBRec.lnMessage, Message);
            vdDisplayAt(1, 1, Message, NO_CLEAR);
        }
    }
    return(VS_SUCCESS);
}


int inCPACRenameReversalFile(TRANSACTION_OBJECT* pobTran) {
    char szSourceReversalFileName[20];
    char szDestReversalFielName[20];

    vdGetReversalFileName(szSourceReversalFileName, inGetHostIndex());
    sprintf(szDestReversalFielName, "%s.%s", szSourceReversalFileName, "rev");
    strcat(szSourceReversalFileName, ".BAK");
    file_copy(szSourceReversalFileName, szDestReversalFielName);

    return(VS_SUCCESS);
}



int inCPACLoadVoidIssueNumber(TRANSACTION_OBJECT* pobTran) {
    int inIssuer;
    // unsigned char ucIITTempRec[SIZE_IIT_REC+1];
    inIssuer = atoi(pobTran->srBRec.szIssueNumber);

    // inIssuer = inGetIssuerNum();

    inLoadCDTRec(pobTran->srBRec.inCDTIndex);
    if (inGetIssuerRecord(inGetIssuerNum()) == VS_ERR)
        vdSGErrorMessage(IIT_ERR_MSG21);

    strcpy(srRcpt.unFrm.srReceipt.szCType, szGetIssuerLabel());
    return(VS_SUCCESS);
}


int inClearCHolder(TRANSACTION_OBJECT* pobTran) {
    pdebug(("Clear Cholder "));

    if (pobTran->inOperationCode == BATCH_REVIEW_OPERATION)
        return(VS_SUCCESS);
    else
        memset(pobTran->srBRec.szCHolder, 0, CHOLDER_SIZE + 1);
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inEditCSTOperation |
*       Edit the CST configuration table
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc return values.
* @flag int    |  BRANCH_EXIT
* @end
**********************************************************************************************/
int inEditCSTOperation(TRANSACTION_OBJECT* pobTran) {
    /** /pdebug(("--inEditCSTOperation--"));*/
    inConfRecEdit("CST");

    return(BRANCH_EXIT);
}
/*********************************************************************************************
* @func int | inEditLCTOperation |
*       Edit the CST configuration table
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @rdesc return values.
* @flag int    |  BRANCH_EXIT
* @end
**********************************************************************************************/
int inEditLCTOperation(TRANSACTION_OBJECT* pobTran) {
    /** /pdebug(("--inEditLCTOperation--"));*/
    inConfRecEdit("LCT");

    return(BRANCH_EXIT);
}

int inClearErrorMsg(TRANSACTION_OBJECT* pobTran) {
    vdSGErrorMessage(0l);
    return(VS_SUCCESS);
}

/*  The download logo funtion to implement multilogo functionality */
#ifdef DOWNLOAD_MULTIPLE_LOGO
int inMultipleDownloadLogo(int inWhichOne) {
    char szLCTLogoFileName[FILENAME_SIZE + 1];
    char szTemp[20];
    int inHandleLogoFile = -1;
    int inRetval = -1;

    // JTB This sets up the ACT2000 formater engine with a pointer to gvardata
    //     This is needed when using ACT2000 as a shared library

    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter())
        return(VS_SUCCESS);

    if (inWhichOne == 1)
        inWhichOne = ((int) lnGetInvNum() % 2) + 1;

    memset(szTemp, 0, sizeof(szTemp));
    strcpy(szTemp, szGetHostFileName());

    sprintf(szLCTLogoFileName, "%slog%d.lgo", szTemp, inWhichOne);

    inHandleLogoFile = open(szLCTLogoFileName, O_RDONLY);

    if (inHandleLogoFile > 0) /* File Opened Successfully */ {
        inRetval = shDnldGraphicFns[obPrinter.inType] (obPrinter.inHandle, inHandleLogoFile);
        SVC_WAIT(300);
        close(inHandleLogoFile);
        return (VS_SUCCESS);
    }

    return (VS_SUCCESS);
}
#else
int inMultipleDownloadLogo(int inWhichOne) {
    return(VS_SUCCESS);
}
#endif /* DOWNLOAD_MULTIPLE_LOGO */
int inCPACCloseFormaterHandle(TRANSACTION_OBJECT* pobTran) {
    inCloseFormater();

    return (VS_SUCCESS);
}

int inCPACClearAdvice(TRANSACTION_OBJECT* pobTran) {
    char szFileName[FILENAME_SIZE + 1];
    int inHandle,
    inRecNum;
    char szInvNum[INV_NUM_SIZE + 1];
    //char szTemp [MESSAGE_SIZE +1];

    memset(szFileName, 0, sizeof(szFileName));
    memset(szInvNum, 0, sizeof(szInvNum));
    sprintf(szInvNum, "%06ld", pobTran->srBKey.lnInvNum);
    vdGetReversalFileName((char *) szFileName, inGetHostHandle());  // get the base file name
    //       vdDisplayAt(1, 1, szFileName, CLR_EOL); // get_char();
    strcat(szFileName, ROC_FILE_EXTN);
    inHandle = open(szFileName, O_RDWR);
    if (inHandle < 0)
        return (VS_SUCCESS);
    SVC_WAIT(400); // Don't even think about removing these dalays!!!
    //       vdDisplayAt(1, 2, szInvNum, CLR_EOL); // get_char();
    inRecNum = search_roc(inHandle, (unsigned char *) szInvNum, 0);

    if (inRecNum < 0) {
        close(inHandle);
        return(VS_SUCCESS);
    } else {
        SVC_WAIT(400); // Don't even think about removing these dalays!!!
        //             sprintf (szTemp, " Deleting %02d", inRecNum); vdDisplayAt(1, 3, szTemp, CLR_EOL); //get_char();
        delete_roc(inHandle, inRecNum);   // delete the roc file name
        close(inHandle);
    }

    // now we need to delete the advice file name
    szFileName[strlen(szFileName) - 4] = NULL_CH;
    strcat(szFileName, OFFLINE_FILE_EXTN);
    inHandle = open(szFileName, O_RDWR);

    seek_ivlr(inHandle, (long) inRecNum, SEEK_SET);

    delete_ivlr(inHandle, 1);
    close(inHandle);
    return (VS_SUCCESS);
}


int inCPACCheckValidInvNum(TRANSACTION_OBJECT* pobTran) {
    if (inGCPACHostSelectedIndex != inGetHostHandle()) {
        vdDisplayErrorMessage(NO_MATCH_MSG21);
        return(VS_ERROR);
    }

    return (VS_SUCCESS);
}


int inCPACStoreSelectedHostIndex(TRANSACTION_OBJECT* pobTran) {
    inGCPACHostSelectedIndex = (int) shGetHostGroupRef();
    return (VS_SUCCESS);
}



#ifdef UPDATE_REV_STAN    /*   Saritha_b1 changed from TLFB to UPDATE_REV_STAN */

/*
    This function is used to update the reversal STAN with the current STAN
*/

int inCPACModifyReversal(TRANSACTION_OBJECT* pobTran) {
    char szFileName[FILENAME_SIZE + 1];
    int inHandle,
    inRetVal;
    char szInvNum[INV_NUM_SIZE + 1];
    COMM_8583_DATA* p_c8583_data ;
    int i = 0;
    field_struct* p_field_array1;
    field_struct* p_fld_amount;
    char* pstan = NULL;
    char* loc_amount = NULL;
    long lStan = 0 ;
    VALIDATION_STRUCT* p_lv_parms; /* local pointer to the validation parameters LENZ */
    HOST_8583_DATA* psrHostData1;
    if ((psrHostData1 = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData1);
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("No Memory: aSendReceiveCPAC 00");
        return(VS_ERR);
    }

    if ((psrHostData1->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_TRUE)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        ACTIVITY_LOG("No Memory: SendReceiveCPAC 01");
        vdFreeISO8583Data(psrHostData1);
        return(VS_ERR);
    }

	psrHostData1->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData1->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData1->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData1->c8583_data->v_parms))->comm_struct = psrHostData1->c8583_data;
    /* Added for Custom base resp validation CPAC_VALID */




    p_c8583_data = psrHostData1->c8583_data;

    p_lv_parms = (VALIDATION_STRUCT *) p_c8583_data->v_parms; //LENZ

    memset(szFileName, 0, sizeof(szFileName));
    memset(szInvNum, 0, sizeof(szInvNum));
    strcpy(szFileName, (char *) p_c8583_data->base_fname);
    vdGetReversalFileName(szFileName, inGetHostHandle());

    strcat(szFileName, REVERSAL_FILE_EXTN);
    inHandle = open(szFileName, O_RDWR);

    if (inHandle < 0) {
        /* Releasing allocated memory */
        vdFreeCommData(psrHostData1->c8583_data);
        vdFreeHostData(psrHostData1);
        vdFreeVariantTables();
        return (VS_SUCCESS);
    }

    inRetVal = read_and_disassemble(p_c8583_data, RV_BUF, inHandle, 0, SEEK_SET);
    p_fld_amount = find_field_index(4, p_c8583_data->p_fld_table);
    loc_amount = p_fld_amount->reference;
    p_field_array1 = find_field_index(11, p_fld_amount);
    pstan = p_field_array1->reference;

    memcpy(&lStan, pstan, sizeof(long)) ;

    lStan = lnGetSTAN();
    memcpy(pstan, &lStan, sizeof(long)) ;


    p_lv_parms->b_trace = lStan;
    *(p_lv_parms->p_trace) = lStan;
    assemble_and_store(p_c8583_data, RV_BUF, inHandle, 0, SEEK_SET, UPDATE_REC);
    inIncSTAN() ;

    close(inHandle);

    /* Releasing allocated memory */
    vdFreeCommData(psrHostData1->c8583_data);
    vdFreeHostData(psrHostData1);
    vdFreeVariantTables();

    return (VS_SUCCESS);
}

#endif /*  UPDATE_REV_STAN  */


/*
 This function is used to update the advice record in the advice file maintained by PIP engine with the
 current value of the STAN.
*/

#ifdef UPDATE_ADV_STAN

int inCPACModifyAdvice(HOST_8583_DATA* host_struct) {
    char szFileName[FILENAME_SIZE + 1];
    int inHandle;
    char szInvNum[INV_NUM_SIZE + 1];
    COMM_8583_DATA* p_c8583_data ;
    int i = 0;
    field_struct* p_field_array1;
    field_struct* p_fld_amount;
    char* pstan = NULL;
    char* loc_amount = NULL;
    long lStan = 0 ;
    VALIDATION_STRUCT* p_lv_parms; /* local pointer to the validation parameters LENZ */


    p_c8583_data = host_struct->c8583_data;

    p_lv_parms = (VALIDATION_STRUCT *) p_c8583_data->v_parms; //LENZ


    memset(szFileName, 0, sizeof(szFileName));
    memset(szInvNum, 0, sizeof(szInvNum));

    strcpy(szFileName, (char *) p_c8583_data->base_fname);

    strcat(szFileName, OFFLINE_FILE_EXTN);
    inHandle = open(szFileName, O_RDWR);

    if (inHandle < 0)
        return (VS_SUCCESS);

    close(inHandle);

    szFileName[strlen(szFileName) - 4] = NULL_CH;
    strcat(szFileName, OFFLINE_FILE_EXTN);
    inHandle = open(szFileName, O_RDWR);


    read_and_disassemble(p_c8583_data, TR_BUF, inHandle, 0, SEEK_SET);
    p_fld_amount = find_field_index(4, p_c8583_data->p_fld_table);
    loc_amount = p_fld_amount->reference;
    p_field_array1 = find_field_index(11, p_fld_amount);
    pstan = p_field_array1->reference;

    memcpy(&lStan, pstan, sizeof(long)) ;

    lStan = lnGetSTAN();
    memcpy(pstan, &lStan, sizeof(long)) ;

    map_reset(p_c8583_data->map, 35);

    p_lv_parms->b_trace = lStan;
    *(p_lv_parms->p_trace) = lStan;
    assemble_and_store(p_c8583_data, TR_BUF, inHandle, 0, SEEK_SET, UPDATE_REC);

    inIncSTAN() ;

    close(inHandle);

    return (VS_SUCCESS);
}

#endif /*   UPDATE_ADV_STAN  ( Saritha_b1 changed from TLFB_LOXBIT  to UPDATE_ADV_STAN) */


/*********************************************************************************************
* @func int | inCPACValidateVoid |
*       Checks if the void is allowed.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
*
* @flag int    |    VS_SUCCESS
*                   VS_ESCAPE
* @end
**********************************************************************************************/

int inCPACValidateVoid(TRANSACTION_OBJECT* pobTran) {
#ifndef IMAM_REMOVE
    TRANSACTION_OBJECT obTran;
    /* added to incorporate SPBASE2.5 change of 06/16/99 gw */
    int inHDTIndex;

    /* This check must be done before loading batch rec TRT */
    if (inCheckBannedCardType(pobTran) == VS_ERR)
        return(VS_ERR);

    /* Load the correct host */
    /*if (inLoadHostData(inGetCDTHostIndex()) != VS_SUCCESS) ALVARO*/
    if (inLoadDefaultHost(inGetHostHandle()) != VS_SUCCESS)
        return(VS_ERR);

    if (inLoadCDTRec(pobTran->srBRec.inCDTIndex) != VS_SUCCESS)
        return(VS_ERR);

    #ifdef  HDFC_INDIA
    if(fGetBase24CDTVoidAllowed() == VS_FALSE) /*venu_void*/
		{
			vdSGErrorMessage(TRANS_NOT_ALLWD_ERR_MSG);
			return (VS_ERR);
		}
    #endif
    inHDTIndex = inGetHostGroupID();

    if (inGCPACHostSelectedIndex != inHDTIndex) {
        vdSGErrorMessage(VOID_NOT_ALLOWED_ERR_MSG);
        return(VS_ERR);
    }

    /* Load TRT locally for batch record    */
    inLoadTRTRec(&obTran, pobTran->srBRec.inCode);

    if (pobTran->srBKey.fVoided) {
        vdSGErrorMessage(ALREADY_VOIDED_ERR_MSG);
        return(VS_ERR);
    }

    /* Check batch record TRT   */
    if (!obTran.srTRTRec.VoidAllowed) {
        vdSGErrorMessage(VOID_NOT_ALLOWED_ERR_MSG);
        return(VS_ERR);
    }
#endif //IMAM_REMOVE
    return (VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inCPACValidateAdjust |
*
*       Checks if the adjust is allowed.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
*
* @flag int    |    VS_SUCCESS
*                   VS_ESCAPE
*                   VS_ERR
* @end
**********************************************************************************************/

int inCPACValidateAdjust(TRANSACTION_OBJECT* pobTran) {
    TRANSACTION_OBJECT obTran;
    int inHDTIndex;
    /* Load TRT locally for batch record    */
    inLoadTRTRec(&obTran, pobTran->srBRec.inCode);

    /* Check batch record TRT   */
    if ((!obTran.srTRTRec.AdjustAllowed) || (pobTran->srBKey.fVoided)) {
        vdSGErrorMessage(ADJ_NOT_ALLOWED_ERR_MSG);
        return(VS_ERR);
    }

    /* prompt for Man PW when limit is reached. */
    if (pobTran->srBRec.inNumberOfAdjusts + pobTran->srBRec.inNumberOfTipAdjusts >= inGetTipMaxAdjust()) {
        vdDisplayMessageFromFile(EXCEED_ADJ_MAX, WARNING_MSG);
        if (inGetPwdFromUser(ACCESS_WITH_MANAGER_PASSWORD, NO_PIT_INDEX) <= VS_ERR) {
            vdSGErrorMessage(ADJ_NOT_ALLOWED_ERR_MSG);
            return (VS_ERR);
        }
        vdClearStatusMessage();
    }

    if (inLoadCDTRec(pobTran->srBRec.inCDTIndex) != VS_SUCCESS)
        return(VS_ERR);

       #ifdef  HDFC_INDIA
       if(fGetBase24CDTAdjustAllowed() == VS_FALSE)/*venu_adjust*/
		{
			vdSGErrorMessage(TRANS_NOT_ALLWD_ERR_MSG);
			return (VS_ERR);
		}

       #endif
    inHDTIndex = inGetHostGroupID();

    if (inGCPACHostSelectedIndex != inHDTIndex) {
        vdSGErrorMessage(ADJ_NOT_ALLOWED_ERR_MSG);
        return(VS_ERR);
    }


    return (VS_SUCCESS);
}
/*---------------------------------------------------------------------------
* Routine Name : void vdCPACLoadValidationStruct
* Description  : Checks the response against the following fields that are
*                stored in the validation structure.
*                -> NII
*                -> PROC CODE
*                -> Message Type Identifier

* Input        : Validation structure.
*                and Bit Map for this transaction.
* Output       : Nil
*------------------------------------------------------------------------------
*/
#if 0
void vdCPACLoadValidationStruct()
{

       strcpy(srAddValStruct.szNII, (char*)srISO.pszField24);
       srAddValStruct.pchNII = (char*)srISO.pszField24;

       memcpy(srAddValStruct.stProcCode, srISO.pszField03, PROC_CODE_SIZE);
       srAddValStruct.pchProcCode = (unsigned char*) srISO.pszField03;

       memcpy(srAddValStruct.stMti, Mti, MTI_SIZE);
       srAddValStruct.pchMti = Mti;
}
#endif /*0 sowmya_to_check*/

int inCPACClearReversal(TRANSACTION_OBJECT* pobTran) {
    int inHostIndex;
    inHostIndex = pobTran->srBKey.inHDTIndex;
    vdReversalsDelete(inHostIndex);
    return (VS_SUCCESS);
}

/* Start......................Fix for Crashing after 24 days Issue...........................Start  */

int inCPACRestartAfter24Days(TRANSACTION_OBJECT *pobTran)
{
#ifndef IMAM_REMOVE
	char szTicks[11 + 1];
	int inLen = 0;
	long lnThreshold = 0L;
	long lnTickCount = 0L;

	if ((inLen = get_env("TICKS", szTicks, sizeof(szTicks))) > 0)
	{
		szTicks[inLen] = NULL_CH;
		lnThreshold= atol(szTicks);
		if (lnThreshold > 0L)
		{
			lnTickCount = read_ticks(); //2073600000
			if (lnTickCount >=  lnThreshold){
				SVC_RESTART("");
            }
        }
    }
#endif
	int inImamRestartMaxCount = inGetImamRestartMaxCount();
	if (read_ticks() > (60*60*23*1000L)){  //23 jam sekali
		inImamRestartFlag = 9999;
	}
	if ((inImamRestartMaxCount>=1) && (inImamRestartMaxCount<=inImamRestartFlag)){
		inImamRestartFlag = 0;
		vdImamClearScreen();
		DisplayStatus("EDC IS RESTARTING TO");
		vdScrollDisplay();
		DisplayStatus("IMPROVE PERFORMANCE.");
		vdScrollDisplay();
		DisplayStatus("PLEASE WAIT...");
		vdScrollDisplay();
		inImamReleaseComm();
		SVC_WAIT(2000);
		SVC_RESTART("");
	}
    return(VS_SUCCESS);
}

/* End........................Fix for Crashing after 24 days Issue...........................End  */

int inCPACPrintPacketLog(TRANSACTION_OBJECT *pobTran)
{
	int inResult;

	inResult = inPrintISO8583PacketLog();
	return inResult;

	//return VS_SUCCESS;
}
void vdCITINormalBeep(int inDelay) {
    int inCount;
    for (inCount = 0; inCount < 3 ; inCount++) {
        vdDelay(inDelay);
        normal_tone();
    }
    vdDelay((inDelay * 3));
}

#ifdef TCPIP_DEFINED

void vdInitializeTCPIPComm(COMM_OBJECT* obCommunication) {
    //COMM_OBJECT   *pobCommunication ;
    //pobCommunication=&obCommunication;
    obCommunication->inLinkType = CONNECT_ONE;
    obCommunication->fLinkUp = VS_TRUE;

    obCommunication->inInitialize = inInitTCPIPCommunication;
    obCommunication->inBegin = inBeginTCPIPCommunication;
    obCommunication->inCheck = inCheckTCPIPCommunication;
    obCommunication->inSend = inSendTCPIPCommunication;
    obCommunication->inReceive = inReceiveTCPIPCommunication;
    obCommunication->inEnd = inEndTCPIPCommunication;
    obCommunication->inFlush = inFlushTCPIPCommunication;
    obCommunication->inDeinitialize = inDeInitTCPIPCommunication;
}

int Send_Modem_AT_Command(char* sCmd,int iLenCmd,char* sRcv) {
    int iRead;
    unsigned long timeout;
    int iLen;
    int rc = 1;


    sCmd[iLenCmd] = 0x0D;       // add NL character
    write(hLan, sCmd, iLenCmd + 1);

    write_at(sCmd, iLenCmd + 2, 1, 3);
    SVC_WAIT(2000);
    rc = 1;
    while (rc == 1)
        rc = read(hLan, sRcv, 1);  // clean up the read buffer first

    timeout = read_ticks() + 30000; // wait maximum 30 seconds for iChip response

    iRead = 0;
    while (read_ticks() < timeout) {
        rc = read(hLan, &sRcv[iRead], 1);
        //      if ((sRcv[iRead] == '\r') || (sRcv[iRead] == '\n'))
        //          break;
        if ((sRcv[iRead] < 0x20) || (sRcv[iRead] > 0x7F))
            continue;
        iRead += rc;
    }
    sprintf(sCmd, "Total read = %d", rc);
    write_at(sCmd, strlen(sCmd), 1, 7);
    get_char();
    //  if ((sRcv[iRead] == '\r') || (sRcv[iRead] == '\n'))
    return iRead;
    //  else
    //      return -1;
}

int Send_LAN_AT_Command(char* sCmd,int iLenCmd,char* sRcv) {
    int iRead;
    unsigned long timeout;
    int iLen;
    int rc;

    sCmd[iLenCmd] = '\r';       // add CR character
    write(hLan, sCmd, iLenCmd + 1);

    timeout = read_ticks() + 5000;  // wait maximum 3 seconds for iChip response

    while (read_ticks() < timeout) {
        iRead = read(hLan, sRcv, 1);
        if ((iRead == 1) && (sRcv[0] == 'I')) {
            iRead = read(hLan, sRcv, 1);
            if ((iRead == 1) && (sRcv[0] == '/')) {
                // case when "I/" received.. i.e. valid response
                iRead = read(hLan, sRcv, 1);
                if ((sRcv[0] >= '0') && (sRcv[0] <= '9')) {
                    // case when numeric
                    iLen = sRcv[0] - '0';
                    while (sRcv[0] != ':') {
                        iRead = read(hLan, sRcv, 1);
                        if ((sRcv[0] < '0') || (sRcv[0] > '9'))
                            break;  // non numeric - error
                        iLen = iLen * 10;   // multiple by 10;
                        iLen = iLen + (sRcv[0] - '0');  // Add the last digit
                    }
                    if (sRcv[0] != ':')
                        break;      // incorrect format, break to the outmost loop

                    iRead = 0;
                    do {
                        rc = read(hLan, &sRcv[iRead], iLen - iRead);
                        iRead += rc;
                    } while (iRead < iLen);

                    return(iRead);
                } else {
                    iRead = read(hLan, &sRcv[1], 20) + 1;
                    return (iRead);
                }
            }
        }
    }

    return -1;
}

int inInitTCPIPCommunication(COMM_OBJECT* obCommunication) {
    int retVal;
    int rc;
    char szHostIPAddress[25 + 1];
    char szMyIPAddress[25 + 1];
    char szSubNetMask[25 + 1];
    char szIChipCom[25 + 1];
    char szPortNumber[25 + 1];
    struct Opn_Blk ob;
    char sCmd[50];
    char sRcv[50];
    int i;
    int inRetVal;



    //obModem = (MODEM_OBJECT *)obCommunication->Data;
    memset(sRcv, 0, sizeof(sRcv));


    //pdebug(("--inInitModemComm--"));





    szHostIPAddress[get_env("#HOSTIP", szHostIPAddress, sizeof(szHostIPAddress))] = NULL;
    szMyIPAddress[get_env("#MYIP", szMyIPAddress, sizeof(szMyIPAddress))] = NULL;
    szSubNetMask[get_env("#NETMASK", szSubNetMask, sizeof(szSubNetMask))] = NULL;
    szIChipCom[get_env("#ICHIPCOM", szIChipCom, sizeof(szIChipCom))] = NULL;
    szPortNumber[get_env("#IPPORT", szPortNumber, sizeof(szPortNumber))] = NULL;

    if ((hLan = open("/dev/com3", 0)) <= 0) {
        write_at("Open I ChipCOM error", 20, 1, inImamLineNumber);
        get_char();
        return(VS_ERR);
    }

    ob.rate = Rt_9600;
    ob.format = Fmt_A8N1;
    ob.protocol = P_char_mode;

    if (set_opn_blk(hLan, &ob) < 0) {
        write_at("Set open block error", 20, 1, inImamLineNumber);
        get_char();
        return (VS_ERR);
    }
    strcpy(sCmd, "DOWN");

    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);

    if (inGetConnectOneResponse(hLan, 1, sRcv) != VS_SUCCESS)
        return(VS_ERR);



    strcpy(sCmd, "E0");
    //clrscr();
    memset(sRcv, 0, sizeof(sRcv));
    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);
    if (inGetConnectOneResponse(hLan, 1, sRcv) != VS_SUCCESS)
        return(VS_ERR);








    strcpy(sCmd, "DIP:");
    strcat(sCmd, szMyIPAddress);
    memset(sRcv, 0, sizeof(sRcv));
    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);
    if (inGetConnectOneResponse(hLan, 1, sRcv) != VS_SUCCESS)
        return(VS_ERR);



    strcpy(sCmd, "STCP:");
    strcat(sCmd, szHostIPAddress);
    strcat(sCmd, ",");
    strcat(sCmd, szPortNumber);
    memset(sRcv, 0, sizeof(sRcv));
    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);
    if (inGetConnectOneResponse(hLan, 1, sRcv) != VS_SUCCESS)
        return(VS_ERR);
    hSocket = atoi(sRcv);




    return(VS_SUCCESS);
}

int inBeginTCPIPCommunication(COMM_OBJECT* obCommunication,int inCPTIndex,VS_BOOL fUsePrimaryLine) {
    return(VS_SUCCESS);
}

int inCheckTCPIPCommunication(COMM_OBJECT* obCommunication) {
    return(VS_SUCCESS);
}
int inSendTCPIPCommunication(COMM_OBJECT* obCommunication,char* pchSendBuff,int inSendSize,VS_BOOL fConfirmSend,int inTimeout,long lnMessage) {
    unsigned char szTransmitBuffer[1024 + 1];
    unsigned char szTmp[25];
    unsigned char szHex[25];
    int iLenHeader;
    memset(szTransmitBuffer, 0x00, sizeof(szTransmitBuffer));
    memset(szTmp, 0x00, sizeof(szTmp));


    sprintf(szTransmitBuffer, "%s%d,%d:", "SSND%:", hSocket, inSendSize + 2);

    iLenHeader = strlen(szTransmitBuffer);
    sprintf(szTmp, "%04d", inSendSize + 2);


    SVC_DSP_2_HEX(szTmp, szHex, 2);
    memcpy(&szTransmitBuffer[iLenHeader], szHex, 2);

    memcpy(&szTransmitBuffer[iLenHeader + 2], pchSendBuff, inSendSize);

    inSendConnectOneCmd(hLan, inSendSize + iLenHeader + 2, szTransmitBuffer);
    if (inGetConnectOneResponse(hLan, 1, szTmp) != VS_SUCCESS)
        return(VS_ERR);

    return (inSendSize);
}

int inReceiveTCPIPCommunication(COMM_OBJECT* obCommunication,char* pchReceiveBuff,int inReceiveSize,int inReceiveTimeout,long lnMessage) {
    unsigned char   sCmd[20];
    unsigned char   szReceiveBuffer[1024 + 5];
    int rc,
    i,
    inLen;
    unsigned char szLength[10];

    //SVC_WAIT(2000);   // Wait for the host to response...
    //strcpy(sCmd,"AT+iSRCV:0,256");
    sprintf(sCmd, "%s:%d,%d", "SRCV", hSocket, 1024);
    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);
    if (inGetConnectOneResponse(hLan, 3, szReceiveBuffer) != VS_SUCCESS)
        return(VS_ERR);

    memset(szLength, 0x00, sizeof(szLength));
    for (i = 0; (szReceiveBuffer[i] != ':') && (i < sizeof(szLength)); i++)
        szLength[i] = szReceiveBuffer[i];

    inLen = atoi(szLength);
    if (inLen > 0) {
        inLen = inLen - 2;
        memcpy(pchReceiveBuff, &szReceiveBuffer[i + 3], inLen); // + 2 is added for 2 bytes of length  in packet
    } else
        inLen = VS_ERR;

    return(inLen);
}
int inEndTCPIPCommunication(COMM_OBJECT* obCommunication) {
    unsigned char sCmd[20];
    unsigned char sRcv[20];
    obCommunication->inLinkType = NO_COMM;
    sprintf(sCmd, "%s:%d", "SCLS", hSocket);
    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);
    if (inGetConnectOneResponse(hLan, 1, sRcv) != VS_SUCCESS)
        return(VS_ERR);
    close(hLan);
    return(VS_SUCCESS);
}
int inFlushTCPIPCommunication(void) {
    return(VS_SUCCESS);
}


int inDeInitTCPIPCommunication(COMM_OBJECT* obCommunication) {
    char sCmd[50];
    char sRcv[50];



    obCommunication->inLinkType = NO_COMM;


    sprintf(sCmd, "%s:%d", "SCLS", hSocket);
    inSendConnectOneCmd(hLan, strlen(sCmd), sCmd);
    if (inGetConnectOneResponse(hLan, 1, sRcv) != VS_SUCCESS)
        return(VS_ERR);
    close(hLan);


    return(VS_SUCCESS);
}


int inSendConnectOneCmd(int hConnectOne,int iLen,char* cmd_buff) {
    int k,
    y;
    int xx;      /* Return value */
    unsigned char command[1024 + 5];


    memset(command, '\0', sizeof(command));
    y = iLen;

    for (k = y + 3; k >= 4; --k) {
        command[k] = cmd_buff[k - 4];
    }

    command[0] = 'A' ;
    command[1] = 'T' ;
    command[2] = '+';
    command[3] = 'i';

    command[y + 4] = '\r';
    command[y + 5] = 0;
    xx = write(hConnectOne, command, y + 5);

    return (xx);
}

int inGetConnectOneResponse(int hConnect,int i_max_wait,char* pbuffer) {
    int h_clock = -1;

    int index = 0;
    int bytes;
    int alphaFlag ;
    int modem_resp = -1;
    long l_max_ticks = 0;
    unsigned char MdmResponseBuf[1024] = {
        0
    };
    int fDataArrived = VS_FALSE;

    if (i_max_wait > 0)
        l_max_ticks = set_itimeout(h_clock, i_max_wait, TM_SECONDS);
    else if (i_max_wait == -1)
        l_max_ticks = set_itimeout(h_clock, (TICKS_PER_SEC / 5), TM_TICKS);


    while (TRUE) {
        index = 0;
        memset(MdmResponseBuf, '\0', sizeof(MdmResponseBuf));
        do {
            bytes = read(hConnect, &MdmResponseBuf[index], 1); // get result code
            if (bytes == 1) {
                fDataArrived = VS_TRUE;
                l_max_ticks = set_itimeout(h_clock, 1, TM_SECONDS);
                index++;
            }
            if (bytes == 0) {
                if (fDataArrived == VS_TRUE) {
                    //clrscr();
                    //printf("Index %s %d", MdmResponseBuf, index); getchar();

                    //break;
                }
            }
        } while ((SVC_TICKS(0, (long *) &l_max_ticks)) && bytes >= 0 && index < sizeof(MdmResponseBuf));

        if (bytes < 0) {
            modem_resp = -1;
            break;
        }

        if (index >= sizeof(MdmResponseBuf)) {
            modem_resp = -1;
            break;
        }

        if (index > 0) {
            if (strncmp(MdmResponseBuf, "I/ERROR", 7) == 0) {
                modem_resp = -1;
                break;
            } else if (strncmp(MdmResponseBuf, "I/OK", 4) == 0) {
                modem_resp = 0;
                break;
            } else {
                memcpy(pbuffer, MdmResponseBuf + 2, index - 3);
                modem_resp = 0;
                break;
            }
        }

        if ((SVC_TICKS(0, (long *) &l_max_ticks)) == 0) {
            modem_resp = -1;
            break;
        }
    };

    return (modem_resp);
}





#endif /* TCPIP_DEFINED */




